@crvouga/sqlite-mem 1.0.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/dist/index.js CHANGED
@@ -9190,8 +9190,629 @@ function executeDetach(stmt, env) {
9190
9190
  return emptyResult(0, env.state.lastInsertRowid);
9191
9191
  }
9192
9192
 
9193
- // src/functions/table-valued.ts
9193
+ // src/functions/window.ts
9194
+ function rowsEqual(left, right) {
9195
+ if (left.length !== right.length) return false;
9196
+ return left.every((value, index) => {
9197
+ const other = right[index];
9198
+ return value === null && other === null || other !== void 0 && compareSql(value, other) === 0;
9199
+ });
9200
+ }
9201
+ function rowNumber(_partition, index) {
9202
+ return index + 1;
9203
+ }
9204
+ function rank(partition, index, orderKeys = partition) {
9205
+ if (index <= 0) return 1;
9206
+ let firstPeer = index;
9207
+ while (firstPeer > 0 && rowsEqual(orderKeys[firstPeer], orderKeys[firstPeer - 1])) firstPeer--;
9208
+ return firstPeer + 1;
9209
+ }
9210
+ function denseRank(partition, index, orderKeys = partition) {
9211
+ if (index <= 0) return 1;
9212
+ let result = 1;
9213
+ for (let i = 1; i <= index; i++) {
9214
+ if (!rowsEqual(orderKeys[i], orderKeys[i - 1])) result++;
9215
+ }
9216
+ return result;
9217
+ }
9218
+ function lag(partition, index, valueIndex = 0, offset = 1, defaultValue = null) {
9219
+ const target = index - Math.max(0, Math.trunc(offset));
9220
+ return target < 0 ? defaultValue : partition[target]?.[valueIndex] ?? null;
9221
+ }
9222
+ function lead(partition, index, valueIndex = 0, offset = 1, defaultValue = null) {
9223
+ const target = index + Math.max(0, Math.trunc(offset));
9224
+ return target >= partition.length ? defaultValue : partition[target]?.[valueIndex] ?? null;
9225
+ }
9226
+ function firstValue(partition, valueIndex = 0, frameStart = 0) {
9227
+ return partition[frameStart]?.[valueIndex] ?? null;
9228
+ }
9229
+ function lastValue(partition, valueIndex = 0, frameEnd = partition.length - 1) {
9230
+ return partition[frameEnd]?.[valueIndex] ?? null;
9231
+ }
9232
+ function nthValue(partition, n, valueIndex = 0, frameStart = 0) {
9233
+ const offset = Math.trunc(n);
9234
+ if (offset <= 0) return null;
9235
+ return partition[frameStart + offset - 1]?.[valueIndex] ?? null;
9236
+ }
9237
+ var windowFunctions = {
9238
+ row_number: rowNumber,
9239
+ rank,
9240
+ dense_rank: denseRank,
9241
+ lag,
9242
+ lead,
9243
+ first_value: firstValue,
9244
+ last_value: lastValue,
9245
+ nth_value: nthValue,
9246
+ ntile: () => 0,
9247
+ cume_dist: () => 0,
9248
+ percent_rank: () => 0
9249
+ };
9250
+
9251
+ // src/executor/pragma-engine.ts
9252
+ var PRAGMA_TVF_NAMES = [
9253
+ "analysis_limit",
9254
+ "application_id",
9255
+ "auto_vacuum",
9256
+ "automatic_index",
9257
+ "busy_timeout",
9258
+ "cache_size",
9259
+ "cache_spill",
9260
+ "cell_size_check",
9261
+ "checkpoint_fullfsync",
9262
+ "collation_list",
9263
+ "compile_options",
9264
+ "count_changes",
9265
+ "data_version",
9266
+ "database_list",
9267
+ "default_cache_size",
9268
+ "defer_foreign_keys",
9269
+ "empty_result_callbacks",
9270
+ "encoding",
9271
+ "foreign_key_check",
9272
+ "foreign_key_list",
9273
+ "foreign_keys",
9274
+ "freelist_count",
9275
+ "full_column_names",
9276
+ "fullfsync",
9277
+ "function_list",
9278
+ "hard_heap_limit",
9279
+ "ignore_check_constraints",
9280
+ "index_info",
9281
+ "index_list",
9282
+ "index_xinfo",
9283
+ "integrity_check",
9284
+ "journal_mode",
9285
+ "journal_size_limit",
9286
+ "legacy_alter_table",
9287
+ "locking_mode",
9288
+ "max_page_count",
9289
+ "module_list",
9290
+ "optimize",
9291
+ "page_count",
9292
+ "page_size",
9293
+ "pragma_list",
9294
+ "query_only",
9295
+ "quick_check",
9296
+ "read_uncommitted",
9297
+ "recursive_triggers",
9298
+ "reverse_unordered_selects",
9299
+ "schema_version",
9300
+ "secure_delete",
9301
+ "short_column_names",
9302
+ "soft_heap_limit",
9303
+ "synchronous",
9304
+ "table_info",
9305
+ "table_list",
9306
+ "table_xinfo",
9307
+ "temp_store",
9308
+ "threads",
9309
+ "trusted_schema",
9310
+ "user_version",
9311
+ "writable_schema"
9312
+ ];
9313
+ var PRAGMA_LIST_NAMES = [
9314
+ "activate_extensions",
9315
+ ...PRAGMA_TVF_NAMES,
9316
+ "case_sensitive_like",
9317
+ "hexkey",
9318
+ "hexrekey",
9319
+ "incremental_vacuum",
9320
+ "key",
9321
+ "lock_proxy_file",
9322
+ "mmap_size",
9323
+ "rekey",
9324
+ "shrink_memory",
9325
+ "temp_store_directory",
9326
+ "textkey",
9327
+ "textrekey",
9328
+ "wal_autocheckpoint",
9329
+ "wal_checkpoint"
9330
+ ].sort((a, b) => a.localeCompare(b));
9331
+ var MEMORY_VTABLE_MODULES = [
9332
+ "bytecode",
9333
+ "dbstat",
9334
+ "fts3",
9335
+ "fts3tokenize",
9336
+ "fts4",
9337
+ "fts4aux",
9338
+ "fts5",
9339
+ "fts5vocab",
9340
+ "json_each",
9341
+ "json_tree",
9342
+ "rtree",
9343
+ "rtree_i32",
9344
+ "tables_used"
9345
+ ];
9346
+ var COMPILE_OPTIONS2 = [
9347
+ "COMPILER=typescript",
9348
+ "ENABLE_FTS3",
9349
+ "ENABLE_FTS4",
9350
+ "ENABLE_FTS5",
9351
+ "ENABLE_JSON1",
9352
+ "ENABLE_RTREE",
9353
+ "THREADSAFE=0"
9354
+ ];
9355
+ var STORAGE_DEFAULTS = {
9356
+ analysis_limit: { column: "analysis_limit", value: 0 },
9357
+ application_id: { column: "application_id", value: 0 },
9358
+ auto_vacuum: { column: "auto_vacuum", value: 0 },
9359
+ automatic_index: { column: "automatic_index", value: 1 },
9360
+ busy_timeout: { column: "timeout", value: 0 },
9361
+ cache_size: { column: "cache_size", value: 2e3 },
9362
+ cache_spill: { column: "cache_spill", value: 2e4 },
9363
+ cell_size_check: { column: "cell_size_check", value: 0 },
9364
+ checkpoint_fullfsync: { column: "checkpoint_fullfsync", value: 1 },
9365
+ count_changes: { column: "count_changes", value: 0 },
9366
+ data_version: { column: "data_version", value: 1 },
9367
+ default_cache_size: { column: "cache_size", value: 2e3 },
9368
+ defer_foreign_keys: { column: "defer_foreign_keys", value: 0 },
9369
+ empty_result_callbacks: { column: "empty_result_callbacks", value: 0 },
9370
+ encoding: { column: "encoding", value: "UTF-8" },
9371
+ freelist_count: { column: "freelist_count", value: 0 },
9372
+ full_column_names: { column: "full_column_names", value: 0 },
9373
+ fullfsync: { column: "fullfsync", value: 0 },
9374
+ hard_heap_limit: { column: "hard_heap_limit", value: 0 },
9375
+ ignore_check_constraints: { column: "ignore_check_constraints", value: 0 },
9376
+ journal_mode: { column: "journal_mode", value: "memory" },
9377
+ journal_size_limit: { column: "journal_size_limit", value: 32768 },
9378
+ legacy_alter_table: { column: "legacy_alter_table", value: 1 },
9379
+ locking_mode: { column: "locking_mode", value: "normal" },
9380
+ max_page_count: { column: "max_page_count", value: 1073741823 },
9381
+ page_size: { column: "page_size", value: 4096 },
9382
+ query_only: { column: "query_only", value: 0 },
9383
+ read_uncommitted: { column: "read_uncommitted", value: 0 },
9384
+ recursive_triggers: { column: "recursive_triggers", value: 0 },
9385
+ reverse_unordered_selects: { column: "reverse_unordered_selects", value: 0 },
9386
+ secure_delete: { column: "secure_delete", value: 2 },
9387
+ short_column_names: { column: "short_column_names", value: 1 },
9388
+ soft_heap_limit: { column: "soft_heap_limit", value: 0 },
9389
+ synchronous: { column: "synchronous", value: 2 },
9390
+ temp_store: { column: "temp_store", value: 0 },
9391
+ threads: { column: "threads", value: 0 },
9392
+ trusted_schema: { column: "trusted_schema", value: 1 },
9393
+ writable_schema: { column: "writable_schema", value: 0 }
9394
+ };
9395
+ function isPragmaTvfName(name) {
9396
+ const lower = name.toLowerCase();
9397
+ if (PRAGMA_TVF_NAMES.includes(lower)) return true;
9398
+ if (lower.startsWith("pragma_")) {
9399
+ return PRAGMA_TVF_NAMES.includes(lower.slice("pragma_".length));
9400
+ }
9401
+ return false;
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
+ }
9453
+ function normalizePragmaKey(name) {
9454
+ const lower = name.toLowerCase();
9455
+ if (PRAGMA_TVF_NAMES.includes(lower)) return lower;
9456
+ if (lower.startsWith("pragma_")) {
9457
+ const stripped = lower.slice("pragma_".length);
9458
+ if (PRAGMA_TVF_NAMES.includes(stripped)) return stripped;
9459
+ return stripped;
9460
+ }
9461
+ return lower;
9462
+ }
9463
+ function queryPragma(name, args, env) {
9464
+ const key = normalizePragmaKey(name);
9465
+ switch (key) {
9466
+ case "foreign_keys":
9467
+ return single("foreign_keys", env.state.foreignKeysEnabled ? 1 : 0);
9468
+ case "user_version":
9469
+ return single("user_version", env.state.userVersion);
9470
+ case "schema_version":
9471
+ return single("schema_version", env.state.schemaVersion);
9472
+ case "table_info":
9473
+ return pragmaTableInfo(args, env, false);
9474
+ case "table_xinfo":
9475
+ return pragmaTableInfo(args, env, true);
9476
+ case "index_list":
9477
+ return pragmaIndexList(args, env);
9478
+ case "index_info":
9479
+ return pragmaIndexInfo(args, env, false);
9480
+ case "index_xinfo":
9481
+ return pragmaIndexInfo(args, env, true);
9482
+ case "foreign_key_list":
9483
+ return pragmaForeignKeyList(args, env);
9484
+ case "foreign_key_check":
9485
+ return pragmaForeignKeyCheck(args, env);
9486
+ case "database_list":
9487
+ return pragmaDatabaseList(env);
9488
+ case "table_list":
9489
+ return pragmaTableList(env);
9490
+ case "collation_list":
9491
+ return {
9492
+ columns: ["seq", "name"],
9493
+ rows: [
9494
+ [0, "RTRIM"],
9495
+ [1, "NOCASE"],
9496
+ [2, "BINARY"]
9497
+ ]
9498
+ };
9499
+ case "compile_options":
9500
+ return { columns: ["compile_options"], rows: COMPILE_OPTIONS2.map((opt) => [opt]) };
9501
+ case "function_list":
9502
+ return pragmaFunctionList();
9503
+ case "module_list":
9504
+ return pragmaModuleList();
9505
+ case "pragma_list":
9506
+ return { columns: ["name"], rows: PRAGMA_LIST_NAMES.map((n) => [n]) };
9507
+ case "integrity_check":
9508
+ case "quick_check":
9509
+ return single(key, "ok");
9510
+ case "optimize":
9511
+ return { columns: ["optimize"], rows: [] };
9512
+ case "page_count":
9513
+ return single("page_count", estimatePageCount(env));
9514
+ default: {
9515
+ const storage = STORAGE_DEFAULTS[key];
9516
+ if (storage) return single(storage.column, storage.value);
9517
+ return { columns: [], rows: [] };
9518
+ }
9519
+ }
9520
+ }
9521
+ function single(column, value) {
9522
+ return { columns: [column], rows: [[value]] };
9523
+ }
9524
+ function estimatePageCount(env) {
9525
+ const objects = env.state.tables.size + env.state.indexes.size + env.state.views.size + env.state.virtualTables.size;
9526
+ return objects === 0 ? 0 : Math.max(1, objects);
9527
+ }
9528
+ function pragmaTableInfo(args, env, xinfo) {
9529
+ const tableName = requireNameArg(args, "table_info");
9530
+ const table = env.state.tables.get(tableName.toLowerCase());
9531
+ if (!table) return { columns: xinfoColumns(xinfo), rows: [] };
9532
+ const rows = table.columns.map((column, cid) => {
9533
+ const pkIndex = table.columns.filter((c) => c.primaryKey).findIndex((c) => c.name === column.name);
9534
+ const pk = column.primaryKey ? pkIndex >= 0 ? pkIndex + 1 : 1 : 0;
9535
+ const dflt = column.defaultExpr ? defaultLiteral(column.defaultExpr) : null;
9536
+ const base = [cid, column.name, column.typeName ?? "", column.notNull ? 1 : 0, dflt, pk];
9537
+ if (xinfo) {
9538
+ let hidden = 0;
9539
+ if (column.generated && !column.generated.stored) hidden = 2;
9540
+ if (column.generated?.stored) hidden = 3;
9541
+ base.push(hidden);
9542
+ }
9543
+ return base;
9544
+ });
9545
+ return { columns: xinfoColumns(xinfo), rows };
9546
+ }
9547
+ function xinfoColumns(xinfo) {
9548
+ return xinfo ? ["cid", "name", "type", "notnull", "dflt_value", "pk", "hidden"] : ["cid", "name", "type", "notnull", "dflt_value", "pk"];
9549
+ }
9550
+ function defaultLiteral(expr) {
9551
+ if (expr.type === "literal")
9552
+ return typeof expr.value === "string" ? `'${expr.value.replace(/'/g, "''")}'` : expr.value;
9553
+ if (expr.type === "null") return "NULL";
9554
+ return null;
9555
+ }
9556
+ function pragmaIndexList(args, env) {
9557
+ const tableName = requireNameArg(args, "index_list");
9558
+ const table = env.state.tables.get(tableName.toLowerCase());
9559
+ if (!table) return { columns: ["seq", "name", "unique", "origin", "partial"], rows: [] };
9560
+ const rows = [];
9561
+ let seq = 0;
9562
+ for (const name of table.indexes) {
9563
+ const index = env.state.indexes.get(name.toLowerCase());
9564
+ if (!index) continue;
9565
+ rows.push([seq++, index.name, index.unique ? 1 : 0, indexOrigin(index), index.where ? 1 : 0]);
9566
+ }
9567
+ return { columns: ["seq", "name", "unique", "origin", "partial"], rows };
9568
+ }
9569
+ function indexOrigin(index) {
9570
+ if (index.originalSql) return "c";
9571
+ if (index.name.toLowerCase().startsWith("sqlite_autoindex_") && index.unique) return "u";
9572
+ return "c";
9573
+ }
9574
+ function pragmaIndexInfo(args, env, xinfo) {
9575
+ const indexName = requireNameArg(args, "index_info");
9576
+ const index = env.state.indexes.get(indexName.toLowerCase());
9577
+ const columns = xinfo ? ["seqno", "cid", "name", "desc", "coll", "key"] : ["seqno", "cid", "name"];
9578
+ if (!index) return { columns, rows: [] };
9579
+ const table = env.state.tables.get(index.tableName.toLowerCase());
9580
+ const rows = index.columns.map((column, seqno) => {
9581
+ const cid = table?.columns.findIndex((c) => c.name.toLowerCase() === column.name.toLowerCase()) ?? -1;
9582
+ const base = [seqno, cid, column.name];
9583
+ if (xinfo) {
9584
+ base.push(column.order === "DESC" ? 1 : 0, (column.collate ?? "BINARY").toUpperCase(), 1);
9585
+ }
9586
+ return base;
9587
+ });
9588
+ if (xinfo) {
9589
+ rows.push([index.columns.length, -1, null, 0, "BINARY", 0]);
9590
+ }
9591
+ return { columns, rows };
9592
+ }
9593
+ function pragmaForeignKeyList(args, env) {
9594
+ const tableName = requireNameArg(args, "foreign_key_list");
9595
+ const table = env.state.tables.get(tableName.toLowerCase());
9596
+ const columns = ["id", "seq", "table", "from", "to", "on_update", "on_delete", "match"];
9597
+ if (!table) return { columns, rows: [] };
9598
+ const rows = [];
9599
+ let id = 0;
9600
+ for (const constraint of table.constraints) {
9601
+ if (constraint.type !== "foreign_key") continue;
9602
+ const refColumns = constraint.refColumns ?? env.state.tables.get(constraint.refTable.toLowerCase())?.columns.filter((c) => c.primaryKey).map((c) => c.name) ?? [];
9603
+ constraint.columns.forEach((column, seq) => {
9604
+ rows.push([
9605
+ id,
9606
+ seq,
9607
+ constraint.refTable,
9608
+ column,
9609
+ refColumns[seq] ?? null,
9610
+ constraint.onUpdate ?? "NO ACTION",
9611
+ constraint.onDelete ?? "NO ACTION",
9612
+ "NONE"
9613
+ ]);
9614
+ });
9615
+ id++;
9616
+ }
9617
+ return { columns, rows };
9618
+ }
9619
+ function pragmaForeignKeyCheck(args, env) {
9620
+ const columns = ["table", "rowid", "parent", "fkid"];
9621
+ const filter = args[0] != null && args[0] !== null ? String(args[0]).toLowerCase() : null;
9622
+ const rows = [];
9623
+ for (const table of env.state.tables.values()) {
9624
+ if (filter && table.name.toLowerCase() !== filter) continue;
9625
+ let fkid = 0;
9626
+ for (const constraint of table.constraints) {
9627
+ if (constraint.type !== "foreign_key") continue;
9628
+ const parent = env.state.tables.get(constraint.refTable.toLowerCase());
9629
+ const refColumns = constraint.refColumns ?? parent?.columns.filter((c) => c.primaryKey).map((c) => c.name) ?? [];
9630
+ for (const row of table.scan()) {
9631
+ let allNull = true;
9632
+ const childValues = [];
9633
+ for (const col of constraint.columns) {
9634
+ const value = row.values.get(col.toLowerCase()) ?? null;
9635
+ childValues.push(value);
9636
+ if (value !== null) allNull = false;
9637
+ }
9638
+ if (allNull) continue;
9639
+ if (!parent || !parentHasMatch(parent, refColumns, childValues)) {
9640
+ rows.push([table.name, row.rowid, constraint.refTable, fkid]);
9641
+ }
9642
+ }
9643
+ fkid++;
9644
+ }
9645
+ }
9646
+ return { columns, rows };
9647
+ }
9648
+ function parentHasMatch(parent, refColumns, childValues) {
9649
+ if (refColumns.length === 0) return false;
9650
+ for (const row of parent.scan()) {
9651
+ let ok = true;
9652
+ for (let i = 0; i < refColumns.length; i++) {
9653
+ const parentVal = row.values.get(refColumns[i].toLowerCase()) ?? null;
9654
+ if (!sqlValuesEqual(parentVal, childValues[i] ?? null)) {
9655
+ ok = false;
9656
+ break;
9657
+ }
9658
+ }
9659
+ if (ok) return true;
9660
+ }
9661
+ return false;
9662
+ }
9663
+ function sqlValuesEqual(a, b) {
9664
+ if (a === null || b === null) return a === b;
9665
+ if (typeof a === "number" && typeof b === "number") return a === b;
9666
+ if (typeof a === "bigint" || typeof b === "bigint") {
9667
+ return BigInt(a) === BigInt(b);
9668
+ }
9669
+ if (a instanceof Uint8Array || b instanceof Uint8Array) return false;
9670
+ return String(a) === String(b);
9671
+ }
9672
+ function pragmaDatabaseList(env) {
9673
+ const rows = [[0, "main", ""]];
9674
+ let seq = 2;
9675
+ for (const [name, attached] of env.state.attached) {
9676
+ const file = attached.filename === ":memory:" ? "" : attached.filename;
9677
+ rows.push([seq++, name, file]);
9678
+ }
9679
+ return { columns: ["seq", "name", "file"], rows };
9680
+ }
9681
+ function pragmaTableList(env) {
9682
+ const columns = ["schema", "name", "type", "ncol", "wr", "strict"];
9683
+ const rows = [];
9684
+ for (const table of env.state.tables.values()) {
9685
+ rows.push(["main", table.name, "table", table.columns.length, table.withoutRowid ? 1 : 0, table.strict ? 1 : 0]);
9686
+ }
9687
+ for (const view of env.state.views.values()) {
9688
+ const ncol = view.columns?.length ?? 0;
9689
+ rows.push(["main", view.name, "view", ncol, 0, 0]);
9690
+ }
9691
+ for (const vt of env.state.virtualTables.values()) {
9692
+ rows.push(["main", vt.name, "virtual", vt.columns.length, 0, 0]);
9693
+ }
9694
+ rows.push(["main", "sqlite_schema", "table", 5, 0, 0]);
9695
+ rows.push(["temp", "sqlite_temp_schema", "table", 5, 0, 0]);
9696
+ for (const [schema] of env.state.attached) {
9697
+ rows.push([schema, "sqlite_schema", "table", 5, 0, 0]);
9698
+ }
9699
+ return { columns, rows };
9700
+ }
9701
+ function pragmaFunctionList() {
9702
+ const columns = ["name", "builtin", "type", "enc", "narg", "flags"];
9703
+ const rows = [];
9704
+ const add = (name, type, narg, flags) => {
9705
+ rows.push([name, 1, type, "utf8", narg, flags]);
9706
+ };
9707
+ for (const name of Object.keys(getScalarFunctions())) add(name, "s", -1, 2099200);
9708
+ for (const name of Object.keys(dateTimeFunctions)) add(name, "s", -1, 2099200);
9709
+ for (const name of Object.keys(jsonScalarFunctions)) add(name, "s", -1, 2099200);
9710
+ for (const name of Object.keys(mathFunctions)) add(name, "s", -1, 2099200);
9711
+ for (const name of Object.keys(ftsAuxFunctions)) add(name, "s", -1, 2099200);
9712
+ for (const name of Object.keys(rtreeAuxFunctions)) add(name, "s", -1, 2099200);
9713
+ for (const name of Object.keys(aggregateFunctions)) {
9714
+ add(name, "w", name === "count" ? 0 : 1, 2097152);
9715
+ if (name === "count") add(name, "w", 1, 2097152);
9716
+ }
9717
+ for (const name of Object.keys(jsonAggregateFunctions)) add(name, "w", -1, 2097152);
9718
+ for (const name of Object.keys(windowFunctions)) add(name, "w", -1, 2097152);
9719
+ for (const name of ["generate_series", "json_each", "json_tree"]) {
9720
+ add(name, "s", -1, 2099200);
9721
+ }
9722
+ rows.sort((a, b) => String(a[0]).localeCompare(String(b[0])) || Number(a[4]) - Number(b[4]));
9723
+ return { columns, rows };
9724
+ }
9725
+ function pragmaModuleList() {
9726
+ const names = /* @__PURE__ */ new Set([
9727
+ ...MEMORY_VTABLE_MODULES,
9728
+ ...PRAGMA_TVF_NAMES.map((n) => `pragma_${n}`),
9729
+ "generate_series",
9730
+ "json_each",
9731
+ "json_tree"
9732
+ ]);
9733
+ return {
9734
+ columns: ["name"],
9735
+ rows: [...names].sort((a, b) => a.localeCompare(b)).map((name) => [name])
9736
+ };
9737
+ }
9738
+ function requireNameArg(args, pragma) {
9739
+ if (args.length === 0 || args[0] == null) {
9740
+ throw new SqliteError(`missing pragma argument for ${pragma}`, "misuse");
9741
+ }
9742
+ const value = args[0];
9743
+ if (typeof value === "string") return value;
9744
+ if (typeof value === "number" || typeof value === "bigint") return String(value);
9745
+ throw new SqliteError(`invalid pragma argument for ${pragma}`, "misuse");
9746
+ }
9747
+ function evalPragmaArgs(expr, env) {
9748
+ if (expr === null) return [];
9749
+ if (expr.type === "column" && expr.table === null) return [expr.name];
9750
+ if (expr.type === "literal") return [expr.value];
9751
+ return [evalExpr(expr, env.createEvalContext())];
9752
+ }
9753
+ function evalPragmaSetValue(expr, env) {
9754
+ if (expr.type === "column" && expr.table === null) {
9755
+ const keyword = expr.name.toLowerCase();
9756
+ if (keyword === "on" || keyword === "true" || keyword === "yes") return 1;
9757
+ if (keyword === "off" || keyword === "false" || keyword === "no") return 0;
9758
+ return expr.name;
9759
+ }
9760
+ return evalExpr(expr, env.createEvalContext());
9761
+ }
9762
+ function coercePragmaInt(value) {
9763
+ if (typeof value === "number") return Math.trunc(value);
9764
+ if (typeof value === "bigint") return Number(value);
9765
+ if (typeof value === "string") {
9766
+ const n = Number.parseInt(value, 10);
9767
+ return Number.isFinite(n) ? n : 0;
9768
+ }
9769
+ const asInt = toInteger(value);
9770
+ return asInt === null ? 0 : typeof asInt === "bigint" ? Number(asInt) : asInt;
9771
+ }
9772
+ function coercePragmaTruthy(value) {
9773
+ return isTruthySql(value) === true;
9774
+ }
9775
+
9776
+ // src/functions/table-valued-registry.ts
9194
9777
  var registry = /* @__PURE__ */ new Map();
9778
+ function registerTableValuedFunction(name, fn) {
9779
+ registry.set(name.toLowerCase(), fn);
9780
+ }
9781
+ function getTableValuedFunction(name) {
9782
+ return registry.get(name.toLowerCase());
9783
+ }
9784
+ function hasRegisteredTableValuedFunction(name) {
9785
+ return registry.has(name.toLowerCase());
9786
+ }
9787
+
9788
+ // src/functions/pragma-tvf.ts
9789
+ function toTvfResult(alias, defaultName, columns, rows) {
9790
+ const table = alias ?? defaultName;
9791
+ return {
9792
+ columns,
9793
+ rows: rows.map((row) => ({
9794
+ cells: columns.map((name, index) => ({
9795
+ table,
9796
+ name,
9797
+ value: row[index] ?? null
9798
+ }))
9799
+ }))
9800
+ };
9801
+ }
9802
+ var registered = false;
9803
+ function ensurePragmaTvfsRegistered() {
9804
+ if (registered) return;
9805
+ registered = true;
9806
+ for (const baseName of PRAGMA_TVF_NAMES) {
9807
+ const tvfName = `pragma_${baseName}`;
9808
+ registerTableValuedFunction(tvfName, (args, alias, env) => {
9809
+ const result = queryPragma(baseName, args, env);
9810
+ return toTvfResult(alias, tvfName, result.columns, result.rows);
9811
+ });
9812
+ }
9813
+ }
9814
+
9815
+ // src/functions/table-valued.ts
9195
9816
  var JSON_TVF_COLUMNS = ["key", "value", "type", "atom", "id", "parent", "fullkey", "path"];
9196
9817
  function jsonTvfResult(alias, defaultName, rows) {
9197
9818
  const table = alias ?? defaultName;
@@ -9206,7 +9827,7 @@ function jsonTvfResult(alias, defaultName, rows) {
9206
9827
  }))
9207
9828
  };
9208
9829
  }
9209
- registry.set("generate_series", (args, alias) => {
9830
+ registerTableValuedFunction("generate_series", (args, alias) => {
9210
9831
  if (args.length < 2 || args.length > 3) {
9211
9832
  throw new SqliteError("wrong number of arguments to function generate_series()", "misuse");
9212
9833
  }
@@ -9237,13 +9858,13 @@ registry.set("generate_series", (args, alias) => {
9237
9858
  }
9238
9859
  return { columns: ["value"], rows };
9239
9860
  });
9240
- registry.set("json_each", (args, alias) => {
9861
+ registerTableValuedFunction("json_each", (args, alias) => {
9241
9862
  if (args.length < 1 || args.length > 2) {
9242
9863
  throw new SqliteError("wrong number of arguments to function json_each()", "misuse");
9243
9864
  }
9244
9865
  return jsonTvfResult(alias, "json_each", jsonEachRows(args[0], args[1]));
9245
9866
  });
9246
- registry.set("json_tree", (args, alias) => {
9867
+ registerTableValuedFunction("json_tree", (args, alias) => {
9247
9868
  if (args.length < 1 || args.length > 2) {
9248
9869
  throw new SqliteError("wrong number of arguments to function json_tree()", "misuse");
9249
9870
  }
@@ -9252,12 +9873,24 @@ registry.set("json_tree", (args, alias) => {
9252
9873
  function safeInt(value) {
9253
9874
  return value <= BigInt(Number.MAX_SAFE_INTEGER) && value >= BigInt(Number.MIN_SAFE_INTEGER) ? Number(value) : value;
9254
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
+ }
9255
9883
  function evaluateTableFunction(name, args, alias, env, scope, parent) {
9256
- const fn = registry.get(name.toLowerCase());
9884
+ ensurePragmaTvfsRegistered();
9885
+ const fn = getTableValuedFunction(name);
9257
9886
  if (!fn) throw new SqliteError(`no such table-valued function: ${name}`, "no_such_table");
9258
9887
  const values = args.map((arg) => evalExpr(arg, env.createEvalContext(scope ?? null, parent)));
9259
9888
  return fn(values, alias, env);
9260
9889
  }
9890
+ function hasTableValuedFunction(name) {
9891
+ ensurePragmaTvfsRegistered();
9892
+ return hasRegisteredTableValuedFunction(name);
9893
+ }
9261
9894
 
9262
9895
  // src/schema/catalog.ts
9263
9896
  function schemaCatalogRows(state) {
@@ -9988,10 +10621,10 @@ function executeSelect2(stmt, env, parent) {
9988
10621
  rows = uniqueRows([...leftRows, ...rightRows]);
9989
10622
  break;
9990
10623
  case "INTERSECT":
9991
- rows = uniqueRows(leftRows).filter((row) => rightRows.some((other) => rowsEqual(row, other)));
10624
+ rows = uniqueRows(leftRows).filter((row) => rightRows.some((other) => rowsEqual2(row, other)));
9992
10625
  break;
9993
10626
  case "EXCEPT":
9994
- rows = uniqueRows(leftRows).filter((row) => !rightRows.some((other) => rowsEqual(row, other)));
10627
+ rows = uniqueRows(leftRows).filter((row) => !rightRows.some((other) => rowsEqual2(row, other)));
9995
10628
  break;
9996
10629
  }
9997
10630
  if (stmt.orderBy.length > 0) rows.sort((a, b) => compareCompoundRows(a, b, stmt.orderBy, base.columns));
@@ -10025,7 +10658,7 @@ function executeWith(stmt, env, parent) {
10025
10658
  env.ctes.set(key, valuesToResult(columns, delta));
10026
10659
  const nextResult = executeSelect2(cte.select.compound.select, env, parent);
10027
10660
  const candidates = resultValues(nextResult);
10028
- const additions = cte.select.compound.op === "UNION ALL" ? candidates : candidates.filter((row) => !accumulated.some((existing) => rowsEqual(existing, row)));
10661
+ const additions = cte.select.compound.op === "UNION ALL" ? candidates : candidates.filter((row) => !accumulated.some((existing) => rowsEqual2(existing, row)));
10029
10662
  if (additions.length === 0) break;
10030
10663
  accumulated = [...accumulated, ...additions];
10031
10664
  delta = additions;
@@ -10327,6 +10960,9 @@ function scanFrom(item, env, parent) {
10327
10960
  if (item.type === "table_func") {
10328
10961
  return evaluateTableFunction(item.name, item.args, item.alias, env).rows;
10329
10962
  }
10963
+ if (item.type === "table" && isPragmaTvfName(item.name) && hasTableValuedFunction(item.name.toLowerCase())) {
10964
+ return evaluateTableFunction(item.name, [], item.alias, env, null, parent).rows;
10965
+ }
10330
10966
  const alias = item.alias ?? item.name;
10331
10967
  const qualified = item.schema ? `${item.schema}.${item.name}` : item.name;
10332
10968
  const db = env.state.databaseForSchema(item.schema, qualified);
@@ -10492,7 +11128,16 @@ function shapeOf(item, env) {
10492
11128
  if (item.type === "subquery")
10493
11129
  return resultColumnNames(item.select.columns).map((name) => ({ table: item.alias, name, value: null }));
10494
11130
  if (item.type === "table_func") {
10495
- 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;
11133
+ return columns.map((name) => ({
11134
+ table: item.alias ?? item.name,
11135
+ name,
11136
+ value: null
11137
+ }));
11138
+ }
11139
+ if (item.type === "table" && isPragmaTvfName(item.name) && hasTableValuedFunction(item.name.toLowerCase())) {
11140
+ const columns = tableValuedColumns(item.name) ?? evaluateTableFunction(item.name, [], item.alias, env).columns;
10496
11141
  return columns.map((name) => ({
10497
11142
  table: item.alias ?? item.name,
10498
11143
  name,
@@ -10568,7 +11213,7 @@ function aggregateValue(expr, rows, env, parent) {
10568
11213
  const ctx = env.createEvalContext(row, parent);
10569
11214
  if (expr.filter && isTruthySql(evalExpr(expr.filter, ctx)) !== true) continue;
10570
11215
  const args = expr.args === "*" ? [] : expr.args.map((arg) => evalExpr(arg, ctx));
10571
- if (expr.distinct && seen.some((values) => rowsEqual(values, args))) continue;
11216
+ if (expr.distinct && seen.some((values) => rowsEqual2(values, args))) continue;
10572
11217
  seen.push(args);
10573
11218
  accumulator.step(args);
10574
11219
  }
@@ -10579,7 +11224,7 @@ function windowValue(expr, current, rows, env, parent, namedWindows) {
10579
11224
  const currentCtx = env.createEvalContext(current, parent);
10580
11225
  const partitionKey = spec.partitionBy.map((item) => evalExpr(item, currentCtx));
10581
11226
  const partition = rows.filter(
10582
- (row) => rowsEqual(
11227
+ (row) => rowsEqual2(
10583
11228
  partitionKey,
10584
11229
  spec.partitionBy.map((item) => evalExpr(item, env.createEvalContext(row, parent)))
10585
11230
  )
@@ -10608,13 +11253,13 @@ function windowValue(expr, current, rows, env, parent, namedWindows) {
10608
11253
  if (name === "row_number") return index + 1;
10609
11254
  if (name === "rank") {
10610
11255
  let first = index;
10611
- while (first > 0 && rowsEqual(orderKeys[first], orderKeys[first - 1])) first--;
11256
+ while (first > 0 && rowsEqual2(orderKeys[first], orderKeys[first - 1])) first--;
10612
11257
  return first + 1;
10613
11258
  }
10614
11259
  if (name === "dense_rank") {
10615
- let rank = 1;
10616
- for (let i = 1; i <= index; i++) if (!rowsEqual(orderKeys[i], orderKeys[i - 1])) rank++;
10617
- return rank;
11260
+ let rank2 = 1;
11261
+ for (let i = 1; i <= index; i++) if (!rowsEqual2(orderKeys[i], orderKeys[i - 1])) rank2++;
11262
+ return rank2;
10618
11263
  }
10619
11264
  const evaluated = args.map((arg) => evalExpr(arg, currentCtx));
10620
11265
  if (name === "lag" || name === "lead") {
@@ -10648,7 +11293,7 @@ function windowValue(expr, current, rows, env, parent, namedWindows) {
10648
11293
  if (name === "cume_dist") {
10649
11294
  if (partition.length === 0) return null;
10650
11295
  let lastPeer = index;
10651
- while (lastPeer + 1 < partition.length && rowsEqual(orderKeys[lastPeer + 1], orderKeys[index])) {
11296
+ while (lastPeer + 1 < partition.length && rowsEqual2(orderKeys[lastPeer + 1], orderKeys[index])) {
10652
11297
  lastPeer++;
10653
11298
  }
10654
11299
  return (lastPeer + 1) / partition.length;
@@ -10656,7 +11301,7 @@ function windowValue(expr, current, rows, env, parent, namedWindows) {
10656
11301
  if (name === "percent_rank") {
10657
11302
  if (partition.length <= 1) return 0;
10658
11303
  let first = index;
10659
- while (first > 0 && rowsEqual(orderKeys[first], orderKeys[first - 1])) first--;
11304
+ while (first > 0 && rowsEqual2(orderKeys[first], orderKeys[first - 1])) first--;
10660
11305
  return first / (partition.length - 1);
10661
11306
  }
10662
11307
  throw new SqliteError(`no such window function: ${expr.func.name}`, "other");
@@ -10681,7 +11326,7 @@ function frameBounds(spec, index, length, ctx, defaultFrameEnd, orderKeys) {
10681
11326
  const isRangeLike = spec.frame.type === "RANGE" || spec.frame.type === "GROUPS";
10682
11327
  let peerFirst = index;
10683
11328
  if (isRangeLike && spec.orderBy.length > 0) {
10684
- while (peerFirst > 0 && rowsEqual(orderKeys[peerFirst], orderKeys[peerFirst - 1])) peerFirst--;
11329
+ while (peerFirst > 0 && rowsEqual2(orderKeys[peerFirst], orderKeys[peerFirst - 1])) peerFirst--;
10685
11330
  }
10686
11331
  const bound = (item, isStart) => {
10687
11332
  switch (item.kind) {
@@ -10703,8 +11348,8 @@ function frameBounds(spec, index, length, ctx, defaultFrameEnd, orderKeys) {
10703
11348
  function frameRows(partition, start, end, index, orderKeys, exclude) {
10704
11349
  let peerFirst = index;
10705
11350
  let peerLast = index;
10706
- while (peerFirst > 0 && rowsEqual(orderKeys[peerFirst], orderKeys[peerFirst - 1])) peerFirst--;
10707
- while (peerLast + 1 < partition.length && rowsEqual(orderKeys[peerLast], orderKeys[peerLast + 1])) peerLast++;
11351
+ while (peerFirst > 0 && rowsEqual2(orderKeys[peerFirst], orderKeys[peerFirst - 1])) peerFirst--;
11352
+ while (peerLast + 1 < partition.length && rowsEqual2(orderKeys[peerLast], orderKeys[peerLast + 1])) peerLast++;
10708
11353
  const rows = [];
10709
11354
  for (let i = Math.max(0, start); i <= end && i < partition.length; i++) {
10710
11355
  if (exclude === "current_row" && i === index) continue;
@@ -10930,7 +11575,7 @@ function referencesTable(select, name) {
10930
11575
  };
10931
11576
  return visit(select.from) || (select.compound ? referencesTable(select.compound.select, name) : false);
10932
11577
  }
10933
- function rowsEqual(left, right) {
11578
+ function rowsEqual2(left, right) {
10934
11579
  return left.length === right.length && left.every((value, index) => {
10935
11580
  const other = right[index] ?? null;
10936
11581
  return value === null && other === null || value !== null && other !== null && sqlValueEquals(value, other);
@@ -12355,154 +13000,24 @@ function asExplicitRowid(value) {
12355
13000
  // src/executor/pragma.ts
12356
13001
  function executePragma(name, expr, env) {
12357
13002
  const key = name.toLowerCase();
12358
- switch (key) {
12359
- case "foreign_keys":
12360
- return pragmaForeignKeys(expr, env);
12361
- case "table_info":
12362
- return pragmaTableInfo(expr, env, false);
12363
- case "table_xinfo":
12364
- return pragmaTableInfo(expr, env, true);
12365
- case "index_list":
12366
- return pragmaIndexList(expr, env);
12367
- case "index_info":
12368
- return pragmaIndexInfo(expr, env);
12369
- case "foreign_key_list":
12370
- return pragmaForeignKeyList(expr, env);
12371
- case "database_list":
12372
- return pragmaDatabaseList(env);
12373
- case "user_version":
12374
- return pragmaIntVersion("user_version", expr, env, "userVersion");
12375
- case "schema_version":
12376
- return pragmaIntVersion("schema_version", expr, env, "schemaVersion");
12377
- default:
12378
- return emptyResult(0, env.state.lastInsertRowid);
12379
- }
12380
- }
12381
- function pragmaForeignKeys(expr, env) {
12382
- if (expr === null) {
12383
- return valuesToResult(["foreign_keys"], [[env.state.foreignKeysEnabled ? 1 : 0]], 0, env.state.lastInsertRowid);
12384
- }
12385
- const value = pragmaValue(expr, env);
12386
- if (!env.transactions.inTransaction) env.state.foreignKeysEnabled = isTruthySql(value) === true;
12387
- return emptyResult(0, env.state.lastInsertRowid);
12388
- }
12389
- function pragmaTableInfo(expr, env, xinfo) {
12390
- const tableName = pragmaTableArg(expr, env);
12391
- const table = env.state.tables.get(tableName.toLowerCase());
12392
- if (!table) return emptyResult(0, env.state.lastInsertRowid);
12393
- const columns = xinfo ? ["cid", "name", "type", "notnull", "dflt_value", "pk", "hidden"] : ["cid", "name", "type", "notnull", "dflt_value", "pk"];
12394
- const rows = table.columns.map((column, cid) => {
12395
- const pkIndex = table.columns.filter((c) => c.primaryKey).findIndex((c) => c.name === column.name);
12396
- const pk = column.primaryKey ? pkIndex >= 0 ? pkIndex + 1 : 1 : 0;
12397
- const dflt = column.defaultExpr ? defaultLiteral(column.defaultExpr) : null;
12398
- const base = [cid, column.name, column.typeName ?? "", column.notNull ? 1 : 0, dflt, pk];
12399
- if (xinfo) {
12400
- let hidden = 0;
12401
- if (column.generated?.stored) hidden = 2;
12402
- else if (column.generated) hidden = 2;
12403
- if (column.generated && !column.generated.stored) hidden = 2;
12404
- if (column.generated?.stored) hidden = 3;
12405
- base.push(hidden);
12406
- }
12407
- return base;
12408
- });
12409
- return valuesToResult(columns, rows, 0, env.state.lastInsertRowid);
12410
- }
12411
- function defaultLiteral(expr) {
12412
- if (expr.type === "literal")
12413
- return typeof expr.value === "string" ? `'${expr.value.replace(/'/g, "''")}'` : expr.value;
12414
- if (expr.type === "null") return "NULL";
12415
- return null;
12416
- }
12417
- function pragmaIndexList(expr, env) {
12418
- const tableName = pragmaTableArg(expr, env);
12419
- const table = env.state.tables.get(tableName.toLowerCase());
12420
- if (!table) return emptyResult(0, env.state.lastInsertRowid);
12421
- const rows = [];
12422
- let seq = 0;
12423
- for (const name of table.indexes) {
12424
- const index = env.state.indexes.get(name.toLowerCase());
12425
- if (!index) continue;
12426
- rows.push([seq++, index.name, index.unique ? 1 : 0, "c", 0]);
12427
- }
12428
- return valuesToResult(["seq", "name", "unique", "origin", "partial"], rows, 0, env.state.lastInsertRowid);
12429
- }
12430
- function pragmaIndexInfo(expr, env) {
12431
- const indexName = pragmaTableArg(expr, env);
12432
- const index = env.state.indexes.get(indexName.toLowerCase());
12433
- if (!index) return emptyResult(0, env.state.lastInsertRowid);
12434
- const table = env.state.getTable(index.tableName);
12435
- const rows = index.columns.map((column, seqno) => {
12436
- const cid = table.columns.findIndex((c) => c.name.toLowerCase() === column.name.toLowerCase());
12437
- return [seqno, cid, column.name];
12438
- });
12439
- return valuesToResult(["seqno", "cid", "name"], rows, 0, env.state.lastInsertRowid);
12440
- }
12441
- function pragmaForeignKeyList(expr, env) {
12442
- const tableName = pragmaTableArg(expr, env);
12443
- const table = env.state.tables.get(tableName.toLowerCase());
12444
- if (!table) return emptyResult(0, env.state.lastInsertRowid);
12445
- const rows = [];
12446
- let id = 0;
12447
- for (const constraint of table.constraints) {
12448
- if (constraint.type !== "foreign_key") continue;
12449
- const refColumns = constraint.refColumns ?? env.state.tables.get(constraint.refTable.toLowerCase())?.columns.filter((c) => c.primaryKey).map((c) => c.name) ?? [];
12450
- constraint.columns.forEach((column, seq) => {
12451
- rows.push([
12452
- id,
12453
- seq,
12454
- constraint.refTable,
12455
- column,
12456
- refColumns[seq] ?? null,
12457
- constraint.onUpdate ?? "NO ACTION",
12458
- constraint.onDelete ?? "NO ACTION",
12459
- "NONE"
12460
- ]);
12461
- });
12462
- id++;
12463
- }
12464
- return valuesToResult(
12465
- ["id", "seq", "table", "from", "to", "on_update", "on_delete", "match"],
12466
- rows,
12467
- 0,
12468
- env.state.lastInsertRowid
12469
- );
12470
- }
12471
- function pragmaDatabaseList(env) {
12472
- const rows = [[0, "main", ""]];
12473
- let seq = 2;
12474
- for (const [name, attached] of env.state.attached) {
12475
- const file = attached.filename === ":memory:" ? "" : attached.filename;
12476
- rows.push([seq++, name, file]);
13003
+ if (key === "foreign_keys" && expr !== null) {
13004
+ const value = evalPragmaSetValue(expr, env);
13005
+ if (!env.transactions.inTransaction) env.state.foreignKeysEnabled = coercePragmaTruthy(value);
13006
+ return emptyResult(0, env.state.lastInsertRowid);
12477
13007
  }
12478
- return valuesToResult(["seq", "name", "file"], rows, 0, env.state.lastInsertRowid);
12479
- }
12480
- function pragmaIntVersion(label, expr, env, field) {
12481
- if (expr === null) {
12482
- return valuesToResult([label], [[env.state[field]]], 0, env.state.lastInsertRowid);
13008
+ if ((key === "user_version" || key === "schema_version") && expr !== null) {
13009
+ const value = evalPragmaSetValue(expr, env);
13010
+ const num2 = coercePragmaInt(value);
13011
+ if (key === "user_version") env.state.userVersion = num2;
13012
+ else env.state.schemaVersion = num2;
13013
+ return emptyResult(0, env.state.lastInsertRowid);
12483
13014
  }
12484
- const value = pragmaValue(expr, env);
12485
- const num2 = typeof value === "number" ? Math.trunc(value) : typeof value === "bigint" ? Number(value) : typeof value === "string" ? Number.parseInt(value, 10) : 0;
12486
- if (field === "userVersion") env.state.userVersion = Number.isFinite(num2) ? num2 : 0;
12487
- else env.state.schemaVersion = Number.isFinite(num2) ? num2 : 0;
12488
- return emptyResult(0, env.state.lastInsertRowid);
12489
- }
12490
- function pragmaTableArg(expr, env) {
12491
- if (!expr) throw new SqliteError("missing pragma argument", "misuse");
12492
- if (expr.type === "column" && expr.table === null) return expr.name;
12493
- if (expr.type === "literal" && typeof expr.value === "string") return expr.value;
12494
- const value = evalExpr(expr, env.createEvalContext());
12495
- if (typeof value === "string") return value;
12496
- throw new SqliteError("invalid pragma argument", "misuse");
12497
- }
12498
- function pragmaValue(expr, env) {
12499
- if (expr.type === "column" && expr.table === null) {
12500
- const keyword = expr.name.toLowerCase();
12501
- if (keyword === "on" || keyword === "true" || keyword === "yes") return 1;
12502
- if (keyword === "off" || keyword === "false" || keyword === "no") return 0;
12503
- return expr.name;
13015
+ const args = evalPragmaArgs(expr, env);
13016
+ const result = queryPragma(key, args, env);
13017
+ if (result.columns.length === 0 && result.rows.length === 0) {
13018
+ return emptyResult(0, env.state.lastInsertRowid);
12504
13019
  }
12505
- return evalExpr(expr, env.createEvalContext());
13020
+ return valuesToResult(result.columns, result.rows, 0, env.state.lastInsertRowid);
12506
13021
  }
12507
13022
 
12508
13023
  // src/executor/execute.ts