@crvouga/sqlite-mem 1.3.1 → 1.5.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 +12 -4
- package/compat/smoke-baseline.json +1 -13
- package/compat/sqllogictest-skip.json +5 -0
- package/dist/index.js +88 -23
- package/dist/index.js.map +3 -3
- package/dist/unstable.js +73 -22
- package/dist/unstable.js.map +3 -3
- package/package.json +6 -1
package/dist/unstable.js
CHANGED
|
@@ -1710,11 +1710,16 @@ function parseDate(value, context) {
|
|
|
1710
1710
|
const date = new Date(source);
|
|
1711
1711
|
return Number.isNaN(date.getTime()) ? null : date;
|
|
1712
1712
|
}
|
|
1713
|
-
function applyModifier(date, modifier) {
|
|
1713
|
+
function applyModifier(date, modifier, flags) {
|
|
1714
1714
|
const result = new Date(date);
|
|
1715
1715
|
const normalized = modifier.trim().toLowerCase();
|
|
1716
1716
|
if (normalized === "unixepoch") return new Date((date.getTime() / 864e5 + JULIAN_UNIX_EPOCH) * 1e3);
|
|
1717
1717
|
if (normalized === "utc" || normalized === "localtime") return result;
|
|
1718
|
+
if (normalized === "subsec" || normalized === "subsecond") {
|
|
1719
|
+
flags.subsec = true;
|
|
1720
|
+
return result;
|
|
1721
|
+
}
|
|
1722
|
+
if (normalized === "floor" || normalized === "ceiling") return result;
|
|
1718
1723
|
const weekday = /^weekday\s+([0-6])$/.exec(normalized);
|
|
1719
1724
|
if (weekday) {
|
|
1720
1725
|
const target = Number(weekday[1]);
|
|
@@ -1753,6 +1758,21 @@ function applyModifier(date, modifier) {
|
|
|
1753
1758
|
}
|
|
1754
1759
|
return result;
|
|
1755
1760
|
}
|
|
1761
|
+
function applyModifiers(date, modifiers) {
|
|
1762
|
+
const flags = { subsec: false };
|
|
1763
|
+
let current = date;
|
|
1764
|
+
for (const modifier of modifiers) {
|
|
1765
|
+
if (typeof modifier !== "string") return null;
|
|
1766
|
+
const next = applyModifier(current, modifier, flags);
|
|
1767
|
+
if (!next) return null;
|
|
1768
|
+
current = next;
|
|
1769
|
+
}
|
|
1770
|
+
return { date: current, subsec: flags.subsec };
|
|
1771
|
+
}
|
|
1772
|
+
function fromUnixSeconds(seconds) {
|
|
1773
|
+
const date = new Date(seconds * 1e3);
|
|
1774
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
1775
|
+
}
|
|
1756
1776
|
function resolveDate(args, context) {
|
|
1757
1777
|
let source = args[0];
|
|
1758
1778
|
let modifiers = args.slice(1);
|
|
@@ -1760,17 +1780,26 @@ function resolveDate(args, context) {
|
|
|
1760
1780
|
if (modifiers[0] === "unixepoch") {
|
|
1761
1781
|
const seconds = coerceToNumber(source);
|
|
1762
1782
|
if (seconds === null) return null;
|
|
1763
|
-
|
|
1764
|
-
|
|
1783
|
+
const date2 = fromUnixSeconds(seconds);
|
|
1784
|
+
if (!date2) return null;
|
|
1785
|
+
return applyModifiers(date2, modifiers.slice(1));
|
|
1786
|
+
}
|
|
1787
|
+
if (typeof modifiers[0] === "string" && modifiers[0].trim().toLowerCase() === "auto") {
|
|
1788
|
+
const number = coerceToNumber(source);
|
|
1789
|
+
if (number === null) {
|
|
1790
|
+
modifiers = modifiers.slice(1);
|
|
1791
|
+
} else if (number >= 0 && number < 53734845e-1) {
|
|
1792
|
+
source = number;
|
|
1793
|
+
modifiers = modifiers.slice(1);
|
|
1794
|
+
} else {
|
|
1795
|
+
const date2 = fromUnixSeconds(number);
|
|
1796
|
+
if (!date2) return null;
|
|
1797
|
+
return applyModifiers(date2, modifiers.slice(1));
|
|
1798
|
+
}
|
|
1765
1799
|
}
|
|
1766
|
-
|
|
1800
|
+
const date = parseDate(source, context);
|
|
1767
1801
|
if (!date) return null;
|
|
1768
|
-
|
|
1769
|
-
if (typeof modifier !== "string") return null;
|
|
1770
|
-
date = applyModifier(date, modifier);
|
|
1771
|
-
if (!date) return null;
|
|
1772
|
-
}
|
|
1773
|
-
return date;
|
|
1802
|
+
return applyModifiers(date, modifiers);
|
|
1774
1803
|
}
|
|
1775
1804
|
function pad(value, length = 2) {
|
|
1776
1805
|
return String(value).padStart(length, "0");
|
|
@@ -1778,8 +1807,9 @@ function pad(value, length = 2) {
|
|
|
1778
1807
|
function isoDate(date) {
|
|
1779
1808
|
return `${pad(date.getUTCFullYear(), 4)}-${pad(date.getUTCMonth() + 1)}-${pad(date.getUTCDate())}`;
|
|
1780
1809
|
}
|
|
1781
|
-
function isoTime(date) {
|
|
1782
|
-
|
|
1810
|
+
function isoTime(date, subsec = false) {
|
|
1811
|
+
const base = `${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}`;
|
|
1812
|
+
return subsec ? `${base}.${pad(date.getUTCMilliseconds(), 3)}` : base;
|
|
1783
1813
|
}
|
|
1784
1814
|
function dayOfYear(date) {
|
|
1785
1815
|
return Math.floor(
|
|
@@ -1823,24 +1853,24 @@ function formatDate(date, format) {
|
|
|
1823
1853
|
var dateTimeFunctions = {
|
|
1824
1854
|
date(args, context) {
|
|
1825
1855
|
const value = resolveDate(args, context);
|
|
1826
|
-
return value ? isoDate(value) : null;
|
|
1856
|
+
return value ? isoDate(value.date) : null;
|
|
1827
1857
|
},
|
|
1828
1858
|
time(args, context) {
|
|
1829
1859
|
const value = resolveDate(args, context);
|
|
1830
|
-
return value ? isoTime(value) : null;
|
|
1860
|
+
return value ? isoTime(value.date, value.subsec) : null;
|
|
1831
1861
|
},
|
|
1832
1862
|
datetime(args, context) {
|
|
1833
1863
|
const value = resolveDate(args, context);
|
|
1834
|
-
return value ? `${isoDate(value)} ${isoTime(value)}` : null;
|
|
1864
|
+
return value ? `${isoDate(value.date)} ${isoTime(value.date, value.subsec)}` : null;
|
|
1835
1865
|
},
|
|
1836
1866
|
julianday(args, context) {
|
|
1837
1867
|
const value = resolveDate(args, context);
|
|
1838
|
-
return value ? value.getTime() / 864e5 + JULIAN_UNIX_EPOCH : null;
|
|
1868
|
+
return value ? value.date.getTime() / 864e5 + JULIAN_UNIX_EPOCH : null;
|
|
1839
1869
|
},
|
|
1840
1870
|
strftime(args, context) {
|
|
1841
1871
|
if (typeof args[0] !== "string") return null;
|
|
1842
1872
|
const value = resolveDate(args.slice(1), context);
|
|
1843
|
-
return value ? formatDate(value, args[0]) : null;
|
|
1873
|
+
return value ? formatDate(value.date, args[0]) : null;
|
|
1844
1874
|
},
|
|
1845
1875
|
current_date(args, context) {
|
|
1846
1876
|
return dateTimeFunctions.date(args.length === 0 ? ["now"] : args, context);
|
|
@@ -1853,7 +1883,7 @@ var dateTimeFunctions = {
|
|
|
1853
1883
|
},
|
|
1854
1884
|
unixepoch(args, context) {
|
|
1855
1885
|
const value = resolveDate(args.length === 0 ? ["now"] : args, context);
|
|
1856
|
-
return value ? Math.floor(value.getTime() / 1e3) : null;
|
|
1886
|
+
return value ? Math.floor(value.date.getTime() / 1e3) : null;
|
|
1857
1887
|
},
|
|
1858
1888
|
timediff(args) {
|
|
1859
1889
|
if (args.length !== 2) return null;
|
|
@@ -3247,9 +3277,9 @@ function evalExpr(expr, ctx) {
|
|
|
3247
3277
|
return result.rows[0]?.[0] ?? null;
|
|
3248
3278
|
}
|
|
3249
3279
|
case "aggregate":
|
|
3250
|
-
throw new SqliteError("aggregate expression requires aggregate evaluation", "misuse");
|
|
3251
|
-
case "window":
|
|
3252
3280
|
throw new SqliteError("window expression requires window evaluation", "misuse");
|
|
3281
|
+
case "window":
|
|
3282
|
+
throw new SqliteError("misuse of window function", "misuse");
|
|
3253
3283
|
case "row":
|
|
3254
3284
|
throw new SqliteError("row value cannot be used as a scalar value", "misuse");
|
|
3255
3285
|
}
|
|
@@ -7957,8 +7987,17 @@ var Table = class _Table {
|
|
|
7957
7987
|
}
|
|
7958
7988
|
return this.maximumRowid === null ? 1 : incrementRowid(this.maximumRowid);
|
|
7959
7989
|
}
|
|
7990
|
+
const maxSigned = 9223372036854775807n;
|
|
7960
7991
|
let candidate = canonicalRowid(this.nextRowid);
|
|
7961
|
-
while (this.rows.has(candidate))
|
|
7992
|
+
while (this.rows.has(candidate)) {
|
|
7993
|
+
if (BigInt(candidate) >= maxSigned) {
|
|
7994
|
+
throw new SqliteError("database or disk is full", "other", "SQLITE_FULL");
|
|
7995
|
+
}
|
|
7996
|
+
candidate = incrementRowid(candidate);
|
|
7997
|
+
}
|
|
7998
|
+
if (BigInt(candidate) > maxSigned) {
|
|
7999
|
+
throw new SqliteError("database or disk is full", "other", "SQLITE_FULL");
|
|
8000
|
+
}
|
|
7962
8001
|
return candidate;
|
|
7963
8002
|
}
|
|
7964
8003
|
advanceNextRowid(rowid) {
|
|
@@ -8715,7 +8754,11 @@ var Reader = class {
|
|
|
8715
8754
|
return utf8Decode(this.raw(this.u32()));
|
|
8716
8755
|
}
|
|
8717
8756
|
json() {
|
|
8718
|
-
|
|
8757
|
+
try {
|
|
8758
|
+
return JSON.parse(this.text(), jsonReviver);
|
|
8759
|
+
} catch {
|
|
8760
|
+
throw new SqliteError("invalid or truncated sqlite-mem snapshot", "other");
|
|
8761
|
+
}
|
|
8719
8762
|
}
|
|
8720
8763
|
value() {
|
|
8721
8764
|
const tag = this.u8();
|
|
@@ -8793,6 +8836,14 @@ function encodeDatabaseState(state, runtime) {
|
|
|
8793
8836
|
return writer.finish();
|
|
8794
8837
|
}
|
|
8795
8838
|
function decodeDatabaseState(snapshot) {
|
|
8839
|
+
try {
|
|
8840
|
+
return decodeDatabaseStateInner(snapshot);
|
|
8841
|
+
} catch (error) {
|
|
8842
|
+
if (error instanceof SqliteError) throw error;
|
|
8843
|
+
throw new SqliteError("invalid or truncated sqlite-mem snapshot", "other");
|
|
8844
|
+
}
|
|
8845
|
+
}
|
|
8846
|
+
function decodeDatabaseStateInner(snapshot) {
|
|
8796
8847
|
const reader = new Reader(snapshot);
|
|
8797
8848
|
const magic = reader.raw(4);
|
|
8798
8849
|
if (!magic.every((byte, index) => byte === MAGIC[index]))
|