@crvouga/sqlite-mem 1.3.1 → 1.4.0
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/compat/divergences.json +22 -1
- package/compat/scenarios.ts +7 -4
- package/compat/smoke-baseline.json +1 -13
- package/dist/index.js +39 -15
- package/dist/index.js.map +2 -2
- package/dist/unstable.js +35 -14
- package/dist/unstable.js.map +2 -2
- package/package.json +1 -1
package/compat/divergences.json
CHANGED
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"scope": "select",
|
|
49
49
|
"predicate": "INDEXED BY / NOT INDEXED is accepted and ignored",
|
|
50
50
|
"specifiedBehavior": "Query results match the unhinted plan; missing-index errors are not raised.",
|
|
51
|
-
"pinnedBy": ["indexes/indexed-by.test.ts"
|
|
51
|
+
"pinnedBy": ["tests/contract/indexes/indexed-by.test.ts"]
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
54
|
"id": "materialized-hint-ignored",
|
|
@@ -119,6 +119,27 @@
|
|
|
119
119
|
"predicate": "user_version is not restored from SQLM",
|
|
120
120
|
"specifiedBehavior": "PRAGMA user_version after restore is the default unless re-set.",
|
|
121
121
|
"pinnedBy": ["PRG-beh-05", "SNP-omit-04"]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"id": "pragma-setter-noop",
|
|
125
|
+
"scope": "pragma",
|
|
126
|
+
"predicate": "Some pragma setters are accepted but do not change engine state yet",
|
|
127
|
+
"specifiedBehavior": "defer_foreign_keys, recursive_triggers, and application_id getters remain 0 after SET.",
|
|
128
|
+
"pinnedBy": ["PRG-beh-02", "PRG-beh-03", "PRG-beh-07"]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"id": "generate-series-extension",
|
|
132
|
+
"scope": "tvf",
|
|
133
|
+
"predicate": "generate_series is a sqlite-mem extension",
|
|
134
|
+
"specifiedBehavior": "Present in sqlite-mem; not claimed vs bun:sqlite default inventory.",
|
|
135
|
+
"pinnedBy": ["FTS-series-01"]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"id": "datetime-localtime-utc",
|
|
139
|
+
"scope": "datetime",
|
|
140
|
+
"predicate": "localtime/utc modifiers do not apply host timezone conversion",
|
|
141
|
+
"specifiedBehavior": "Modifiers are accepted as no-ops; storage remains UTC-like fixed strings.",
|
|
142
|
+
"pinnedBy": ["tests/contract/date-time/modifiers.test.ts"]
|
|
122
143
|
}
|
|
123
144
|
]
|
|
124
145
|
}
|
package/compat/scenarios.ts
CHANGED
|
@@ -37,7 +37,10 @@ function divergenceIdFor(id: string): string | undefined {
|
|
|
37
37
|
}
|
|
38
38
|
if (id === "PRG-fn-01" || id === "PRG-comp-01") return "compile-options-function-list";
|
|
39
39
|
if (id === "PRG-beh-05") return "user-version-snapshot";
|
|
40
|
+
if (id === "PRG-beh-02" || id === "PRG-beh-03" || id === "PRG-beh-07") return "pragma-setter-noop";
|
|
41
|
+
if (id === "FTS-series-01") return "generate-series-extension";
|
|
40
42
|
if (id === "FTS-chg-01") return "fts-shadow-counters";
|
|
43
|
+
if (id === "DAT-mod-localtime" || id === "datetime-localtime-utc") return "datetime-localtime-utc";
|
|
41
44
|
if (id === "ATT-att-01") return "attach-empty-schema";
|
|
42
45
|
if (id === "TOK-07") return "double-quote-string-fallback";
|
|
43
46
|
if (id === "UNI-surr-01") return "lone-surrogate-bind";
|
|
@@ -660,12 +663,12 @@ const TAIL: CatalogSection[] = [
|
|
|
660
663
|
["tl-01", "table_list"],
|
|
661
664
|
["tvf-01", "pragma_* TVFs correlated"],
|
|
662
665
|
["beh-01", "foreign_keys pragma"],
|
|
663
|
-
["beh-02", "defer_foreign_keys"],
|
|
664
|
-
["beh-03", "recursive_triggers"],
|
|
666
|
+
["beh-02", "defer_foreign_keys", D, "setter currently no-op; getter returns 0"],
|
|
667
|
+
["beh-03", "recursive_triggers", D, "setter currently no-op; getter returns 0"],
|
|
665
668
|
["beh-04", "case_sensitive_like"],
|
|
666
669
|
["beh-05", "user_version get/set", D, "snapshot exclusion"],
|
|
667
670
|
["beh-06", "schema_version bumps on DDL"],
|
|
668
|
-
["beh-07", "application_id"],
|
|
671
|
+
["beh-07", "application_id", D, "setter currently no-op; getter returns 0"],
|
|
669
672
|
["health-01", "integrity_check quick_check ok"],
|
|
670
673
|
["health-02", "foreign_key_check rows"],
|
|
671
674
|
["stor-01", "journal_mode memory default"],
|
|
@@ -701,7 +704,7 @@ const TAIL: CatalogSection[] = [
|
|
|
701
704
|
["f34-02", "matchinfo offsets"],
|
|
702
705
|
["chg-01", "shadow-table change counters", D, "README"],
|
|
703
706
|
["snap-01", "virtual tables not in snapshots", D, "README"],
|
|
704
|
-
["series-01", "generate_series"],
|
|
707
|
+
["series-01", "generate_series", D, "sqlite-mem extension; not in bun:sqlite default"],
|
|
705
708
|
]),
|
|
706
709
|
section("ATT", "ATTACH / DETACH / schemas", true, [
|
|
707
710
|
["att-01", "ATTACH anything is empty in-memory schema", D, "filename ignored for data"],
|
package/dist/index.js
CHANGED
|
@@ -3804,6 +3804,7 @@ function valueOf(node) {
|
|
|
3804
3804
|
return jsonNodeToSql(node, "sql");
|
|
3805
3805
|
}
|
|
3806
3806
|
function jsonEachRows(json, path) {
|
|
3807
|
+
if (json === null) return [];
|
|
3807
3808
|
const root = ensureJson(json);
|
|
3808
3809
|
const blob = encodeJsonb(root);
|
|
3809
3810
|
const walk2 = walkJsonbTree(blob);
|
|
@@ -3833,6 +3834,7 @@ function jsonEachRows(json, path) {
|
|
|
3833
3834
|
return walk2.filter((e) => e.parent === focus.idOffset).map((e) => rowFromWalk(e, true));
|
|
3834
3835
|
}
|
|
3835
3836
|
function jsonTreeRows(json, path) {
|
|
3837
|
+
if (json === null) return [];
|
|
3836
3838
|
const root = ensureJson(json);
|
|
3837
3839
|
const blob = encodeJsonb(root);
|
|
3838
3840
|
const walk2 = walkJsonbTree(blob);
|
|
@@ -4291,11 +4293,16 @@ function parseDate(value, context) {
|
|
|
4291
4293
|
const date = new Date(source);
|
|
4292
4294
|
return Number.isNaN(date.getTime()) ? null : date;
|
|
4293
4295
|
}
|
|
4294
|
-
function applyModifier(date, modifier) {
|
|
4296
|
+
function applyModifier(date, modifier, flags) {
|
|
4295
4297
|
const result = new Date(date);
|
|
4296
4298
|
const normalized = modifier.trim().toLowerCase();
|
|
4297
4299
|
if (normalized === "unixepoch") return new Date((date.getTime() / 864e5 + JULIAN_UNIX_EPOCH) * 1e3);
|
|
4298
4300
|
if (normalized === "utc" || normalized === "localtime") return result;
|
|
4301
|
+
if (normalized === "subsec" || normalized === "subsecond") {
|
|
4302
|
+
flags.subsec = true;
|
|
4303
|
+
return result;
|
|
4304
|
+
}
|
|
4305
|
+
if (normalized === "floor" || normalized === "ceiling") return result;
|
|
4299
4306
|
const weekday = /^weekday\s+([0-6])$/.exec(normalized);
|
|
4300
4307
|
if (weekday) {
|
|
4301
4308
|
const target = Number(weekday[1]);
|
|
@@ -4343,15 +4350,21 @@ function resolveDate(args, context) {
|
|
|
4343
4350
|
if (seconds === null) return null;
|
|
4344
4351
|
source = seconds / 86400 + JULIAN_UNIX_EPOCH;
|
|
4345
4352
|
modifiers = modifiers.slice(1);
|
|
4353
|
+
} else if (typeof modifiers[0] === "string" && modifiers[0].trim().toLowerCase() === "auto") {
|
|
4354
|
+
const number = coerceToNumber(source);
|
|
4355
|
+
if (number === null) return null;
|
|
4356
|
+
source = number >= 0 && number < 53734845e-1 ? number : number / 86400 + JULIAN_UNIX_EPOCH;
|
|
4357
|
+
modifiers = modifiers.slice(1);
|
|
4346
4358
|
}
|
|
4347
4359
|
let date = parseDate(source, context);
|
|
4348
4360
|
if (!date) return null;
|
|
4361
|
+
const flags = { subsec: false };
|
|
4349
4362
|
for (const modifier of modifiers) {
|
|
4350
4363
|
if (typeof modifier !== "string") return null;
|
|
4351
|
-
date = applyModifier(date, modifier);
|
|
4364
|
+
date = applyModifier(date, modifier, flags);
|
|
4352
4365
|
if (!date) return null;
|
|
4353
4366
|
}
|
|
4354
|
-
return date;
|
|
4367
|
+
return { date, subsec: flags.subsec };
|
|
4355
4368
|
}
|
|
4356
4369
|
function pad(value, length = 2) {
|
|
4357
4370
|
return String(value).padStart(length, "0");
|
|
@@ -4359,8 +4372,9 @@ function pad(value, length = 2) {
|
|
|
4359
4372
|
function isoDate(date) {
|
|
4360
4373
|
return `${pad(date.getUTCFullYear(), 4)}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}`;
|
|
4361
4374
|
}
|
|
4362
|
-
function isoTime(date) {
|
|
4363
|
-
|
|
4375
|
+
function isoTime(date, subsec = false) {
|
|
4376
|
+
const base = `${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}`;
|
|
4377
|
+
return subsec ? `${base}.${pad(date.getUTCMilliseconds(), 3)}` : base;
|
|
4364
4378
|
}
|
|
4365
4379
|
function dayOfYear(date) {
|
|
4366
4380
|
return Math.floor(
|
|
@@ -4404,24 +4418,24 @@ function formatDate(date, format) {
|
|
|
4404
4418
|
var dateTimeFunctions = {
|
|
4405
4419
|
date(args, context) {
|
|
4406
4420
|
const value = resolveDate(args, context);
|
|
4407
|
-
return value ? isoDate(value) : null;
|
|
4421
|
+
return value ? isoDate(value.date) : null;
|
|
4408
4422
|
},
|
|
4409
4423
|
time(args, context) {
|
|
4410
4424
|
const value = resolveDate(args, context);
|
|
4411
|
-
return value ? isoTime(value) : null;
|
|
4425
|
+
return value ? isoTime(value.date, value.subsec) : null;
|
|
4412
4426
|
},
|
|
4413
4427
|
datetime(args, context) {
|
|
4414
4428
|
const value = resolveDate(args, context);
|
|
4415
|
-
return value ? `${isoDate(value)} ${isoTime(value)}` : null;
|
|
4429
|
+
return value ? `${isoDate(value.date)} ${isoTime(value.date, value.subsec)}` : null;
|
|
4416
4430
|
},
|
|
4417
4431
|
julianday(args, context) {
|
|
4418
4432
|
const value = resolveDate(args, context);
|
|
4419
|
-
return value ? value.getTime() / 864e5 + JULIAN_UNIX_EPOCH : null;
|
|
4433
|
+
return value ? value.date.getTime() / 864e5 + JULIAN_UNIX_EPOCH : null;
|
|
4420
4434
|
},
|
|
4421
4435
|
strftime(args, context) {
|
|
4422
4436
|
if (typeof args[0] !== "string") return null;
|
|
4423
4437
|
const value = resolveDate(args.slice(1), context);
|
|
4424
|
-
return value ? formatDate(value, args[0]) : null;
|
|
4438
|
+
return value ? formatDate(value.date, args[0]) : null;
|
|
4425
4439
|
},
|
|
4426
4440
|
current_date(args, context) {
|
|
4427
4441
|
return dateTimeFunctions.date(args.length === 0 ? ["now"] : args, context);
|
|
@@ -4434,7 +4448,7 @@ var dateTimeFunctions = {
|
|
|
4434
4448
|
},
|
|
4435
4449
|
unixepoch(args, context) {
|
|
4436
4450
|
const value = resolveDate(args.length === 0 ? ["now"] : args, context);
|
|
4437
|
-
return value ? Math.floor(value.getTime() / 1e3) : null;
|
|
4451
|
+
return value ? Math.floor(value.date.getTime() / 1e3) : null;
|
|
4438
4452
|
},
|
|
4439
4453
|
timediff(args) {
|
|
4440
4454
|
if (args.length !== 2) return null;
|
|
@@ -5828,9 +5842,9 @@ function evalExpr(expr, ctx) {
|
|
|
5828
5842
|
return result.rows[0]?.[0] ?? null;
|
|
5829
5843
|
}
|
|
5830
5844
|
case "aggregate":
|
|
5831
|
-
throw new SqliteError("aggregate expression requires aggregate evaluation", "misuse");
|
|
5832
|
-
case "window":
|
|
5833
5845
|
throw new SqliteError("window expression requires window evaluation", "misuse");
|
|
5846
|
+
case "window":
|
|
5847
|
+
throw new SqliteError("misuse of window function", "misuse");
|
|
5834
5848
|
case "row":
|
|
5835
5849
|
throw new SqliteError("row value cannot be used as a scalar value", "misuse");
|
|
5836
5850
|
}
|
|
@@ -8077,8 +8091,17 @@ var Table = class _Table {
|
|
|
8077
8091
|
}
|
|
8078
8092
|
return this.maximumRowid === null ? 1 : incrementRowid(this.maximumRowid);
|
|
8079
8093
|
}
|
|
8094
|
+
const maxSigned = 9223372036854775807n;
|
|
8080
8095
|
let candidate = canonicalRowid(this.nextRowid);
|
|
8081
|
-
while (this.rows.has(candidate))
|
|
8096
|
+
while (this.rows.has(candidate)) {
|
|
8097
|
+
if (BigInt(candidate) >= maxSigned) {
|
|
8098
|
+
throw new SqliteError("database or disk is full", "other", "SQLITE_FULL");
|
|
8099
|
+
}
|
|
8100
|
+
candidate = incrementRowid(candidate);
|
|
8101
|
+
}
|
|
8102
|
+
if (BigInt(candidate) > maxSigned) {
|
|
8103
|
+
throw new SqliteError("database or disk is full", "other", "SQLITE_FULL");
|
|
8104
|
+
}
|
|
8082
8105
|
return candidate;
|
|
8083
8106
|
}
|
|
8084
8107
|
advanceNextRowid(rowid) {
|
|
@@ -12758,7 +12781,6 @@ function executeUpdateCore(stmt, env) {
|
|
|
12758
12781
|
};
|
|
12759
12782
|
if (stmt.where && isTruthySql(evalExpr(stmt.where, env.createEvalContext(joined))) !== true) continue;
|
|
12760
12783
|
matchedScope = joined;
|
|
12761
|
-
break;
|
|
12762
12784
|
}
|
|
12763
12785
|
if (matchedScope) candidates.push({ row, scope: matchedScope });
|
|
12764
12786
|
}
|
|
@@ -13241,7 +13263,9 @@ function applyReferentialDelete(parent, row, env) {
|
|
|
13241
13263
|
for (const candidate of matches) {
|
|
13242
13264
|
if (constraint.onDelete === "CASCADE") {
|
|
13243
13265
|
changes += applyReferentialDelete(child, candidate, env);
|
|
13266
|
+
if (fireDeleteTriggers("BEFORE", child, candidate, env) === "ignore") continue;
|
|
13244
13267
|
removeOne(child, candidate, env);
|
|
13268
|
+
fireDeleteTriggers("AFTER", child, candidate, env);
|
|
13245
13269
|
changes++;
|
|
13246
13270
|
} else if (constraint.onDelete === "SET NULL") {
|
|
13247
13271
|
const updated = updateOne(
|