@crvouga/mockingbird-service-postgres 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/CHANGELOG.md +39 -1
- package/COMPATIBILITY.md +3 -1
- package/README.md +39 -8
- package/compat/coverage.json +1 -1
- package/compat/sections/cat.ts +1 -0
- package/dist/admin.d.ts +13 -0
- package/dist/admin.js +26638 -0
- package/dist/admin.js.map +7 -0
- package/dist/api/database.d.ts +37 -2
- package/dist/ast/nodes.d.ts +11 -2
- package/dist/executor/ddl.d.ts +2 -1
- package/dist/executor/relation.d.ts +5 -0
- package/dist/functions/pgcrypto.d.ts +9 -0
- package/dist/functions/pgtrgm.d.ts +24 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1290 -42
- package/dist/index.js.map +4 -4
- package/dist/runtime/options.d.ts +5 -0
- package/dist/unstable.js +1011 -20
- package/dist/unstable.js.map +4 -4
- package/dist/wire/cli.js +1356 -56
- package/dist/wire/cli.js.map +4 -4
- package/dist/wire/connection.d.ts +5 -0
- package/dist/wire/index.d.ts +18 -2
- package/dist/wire/index.js +1350 -53
- package/dist/wire/index.js.map +4 -4
- package/package.json +8 -1
package/dist/wire/cli.js
CHANGED
|
@@ -3,6 +3,167 @@
|
|
|
3
3
|
// src/wire/index.ts
|
|
4
4
|
import { createServer } from "node:net";
|
|
5
5
|
|
|
6
|
+
// ../../core/dist/timeline.js
|
|
7
|
+
var BRANCH_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/;
|
|
8
|
+
var Timeline = class {
|
|
9
|
+
maxCheckpoints;
|
|
10
|
+
now;
|
|
11
|
+
makeId;
|
|
12
|
+
nodes = /* @__PURE__ */ new Map();
|
|
13
|
+
heads = /* @__PURE__ */ new Map();
|
|
14
|
+
/** Unreferenced nodes in the exact order they became collectible. */
|
|
15
|
+
evictable = /* @__PURE__ */ new Set();
|
|
16
|
+
/** Branch heads plus explicit retainers. Absent means zero. */
|
|
17
|
+
references = /* @__PURE__ */ new Map();
|
|
18
|
+
explicitPins = /* @__PURE__ */ new Map();
|
|
19
|
+
sequence = 0;
|
|
20
|
+
constructor(options2 = {}) {
|
|
21
|
+
const max = options2.maxCheckpoints ?? 1e3;
|
|
22
|
+
if (!Number.isSafeInteger(max) || max < 1)
|
|
23
|
+
throw new RangeError("maxCheckpoints must be a positive integer");
|
|
24
|
+
this.maxCheckpoints = max;
|
|
25
|
+
this.now = options2.now ?? (() => this.sequence);
|
|
26
|
+
this.makeId = options2.id ?? ((sequence) => `cp_${sequence.toString(36).padStart(8, "0")}`);
|
|
27
|
+
}
|
|
28
|
+
/** Capture a new immutable value and move `branch` to it. */
|
|
29
|
+
commit(value, options2 = {}) {
|
|
30
|
+
const branch = options2.branch ?? "main";
|
|
31
|
+
this.assertBranch(branch);
|
|
32
|
+
const parent = options2.parent === void 0 ? this.heads.get(branch) ?? null : options2.parent;
|
|
33
|
+
if (parent !== null && !this.nodes.has(parent))
|
|
34
|
+
throw new RangeError(`no checkpoint ${parent}`);
|
|
35
|
+
const id = this.makeId(++this.sequence);
|
|
36
|
+
if (this.nodes.has(id))
|
|
37
|
+
throw new RangeError(`duplicate checkpoint id ${id}`);
|
|
38
|
+
const checkpoint = Object.freeze({ id, branch, parent, at: this.now(), value });
|
|
39
|
+
this.nodes.set(id, checkpoint);
|
|
40
|
+
this.moveHead(branch, id);
|
|
41
|
+
this.collect(this.maxCheckpoints);
|
|
42
|
+
return checkpoint;
|
|
43
|
+
}
|
|
44
|
+
/** Create a branch pointer without copying its checkpoint value. */
|
|
45
|
+
fork(branch, options2 = {}) {
|
|
46
|
+
this.assertBranch(branch);
|
|
47
|
+
if (this.heads.has(branch))
|
|
48
|
+
throw new RangeError(`branch already exists: ${branch}`);
|
|
49
|
+
const from = options2.from ?? this.heads.get("main");
|
|
50
|
+
if (from === void 0)
|
|
51
|
+
return void 0;
|
|
52
|
+
const checkpoint = this.get(from);
|
|
53
|
+
this.moveHead(branch, checkpoint.id);
|
|
54
|
+
return checkpoint;
|
|
55
|
+
}
|
|
56
|
+
/** Move a branch pointer to an existing checkpoint. */
|
|
57
|
+
checkout(branch, id) {
|
|
58
|
+
this.assertBranch(branch);
|
|
59
|
+
const checkpoint = this.get(id);
|
|
60
|
+
this.moveHead(branch, checkpoint.id);
|
|
61
|
+
return checkpoint;
|
|
62
|
+
}
|
|
63
|
+
get(id) {
|
|
64
|
+
const checkpoint = this.nodes.get(id);
|
|
65
|
+
if (!checkpoint)
|
|
66
|
+
throw new RangeError(`no checkpoint ${id}`);
|
|
67
|
+
return checkpoint;
|
|
68
|
+
}
|
|
69
|
+
head(branch = "main") {
|
|
70
|
+
const id = this.heads.get(branch);
|
|
71
|
+
return id === void 0 ? void 0 : this.get(id);
|
|
72
|
+
}
|
|
73
|
+
hasBranch(branch) {
|
|
74
|
+
return this.heads.has(branch);
|
|
75
|
+
}
|
|
76
|
+
branches() {
|
|
77
|
+
return Object.freeze(Object.fromEntries([...this.heads].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)));
|
|
78
|
+
}
|
|
79
|
+
checkpoints() {
|
|
80
|
+
return [...this.nodes.values()];
|
|
81
|
+
}
|
|
82
|
+
/** Number of retained checkpoints without allocating an array. */
|
|
83
|
+
get size() {
|
|
84
|
+
return this.nodes.size;
|
|
85
|
+
}
|
|
86
|
+
/** Pin a checkpoint independently of branch heads (used by compatibility snapshot handles). */
|
|
87
|
+
retain(id) {
|
|
88
|
+
const checkpoint = this.get(id);
|
|
89
|
+
this.explicitPins.set(id, (this.explicitPins.get(id) ?? 0) + 1);
|
|
90
|
+
this.addReference(id);
|
|
91
|
+
return checkpoint;
|
|
92
|
+
}
|
|
93
|
+
/** Release one explicit pin. Branch heads remain pinned until moved or deleted. */
|
|
94
|
+
release(id) {
|
|
95
|
+
if (!this.nodes.has(id))
|
|
96
|
+
return false;
|
|
97
|
+
const pins = this.explicitPins.get(id) ?? 0;
|
|
98
|
+
if (pins === 0)
|
|
99
|
+
return false;
|
|
100
|
+
if (pins === 1)
|
|
101
|
+
this.explicitPins.delete(id);
|
|
102
|
+
else
|
|
103
|
+
this.explicitPins.set(id, pins - 1);
|
|
104
|
+
this.removeReference(id);
|
|
105
|
+
this.collect(this.maxCheckpoints);
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
deleteBranch(branch) {
|
|
109
|
+
if (branch === "main")
|
|
110
|
+
throw new RangeError("cannot delete main branch");
|
|
111
|
+
const previous = this.heads.get(branch);
|
|
112
|
+
const deleted = this.heads.delete(branch);
|
|
113
|
+
if (previous !== void 0)
|
|
114
|
+
this.removeReference(previous);
|
|
115
|
+
this.collect(this.maxCheckpoints);
|
|
116
|
+
return deleted;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Deterministically discard oldest unpinned checkpoints. Collection is O(number removed):
|
|
120
|
+
* commits never scan pinned nodes or the retained history. Parents are metadata rather than a
|
|
121
|
+
* storage dependency, so a retained node remains usable after pruning.
|
|
122
|
+
*/
|
|
123
|
+
gc(max = this.maxCheckpoints) {
|
|
124
|
+
if (!Number.isSafeInteger(max) || max < 1)
|
|
125
|
+
throw new RangeError("max must be a positive integer");
|
|
126
|
+
const removed = [];
|
|
127
|
+
this.collect(max, removed);
|
|
128
|
+
return removed;
|
|
129
|
+
}
|
|
130
|
+
collect(max, removed) {
|
|
131
|
+
while (this.nodes.size > max && this.evictable.size > 0) {
|
|
132
|
+
const id = this.evictable.values().next().value;
|
|
133
|
+
this.evictable.delete(id);
|
|
134
|
+
this.nodes.delete(id);
|
|
135
|
+
removed?.push(id);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
moveHead(branch, id) {
|
|
139
|
+
const previous = this.heads.get(branch);
|
|
140
|
+
if (previous === id)
|
|
141
|
+
return;
|
|
142
|
+
if (previous !== void 0)
|
|
143
|
+
this.removeReference(previous);
|
|
144
|
+
this.heads.set(branch, id);
|
|
145
|
+
this.addReference(id);
|
|
146
|
+
}
|
|
147
|
+
addReference(id) {
|
|
148
|
+
this.references.set(id, (this.references.get(id) ?? 0) + 1);
|
|
149
|
+
this.evictable.delete(id);
|
|
150
|
+
}
|
|
151
|
+
removeReference(id) {
|
|
152
|
+
const next = (this.references.get(id) ?? 0) - 1;
|
|
153
|
+
if (next > 0)
|
|
154
|
+
this.references.set(id, next);
|
|
155
|
+
else {
|
|
156
|
+
this.references.delete(id);
|
|
157
|
+
if (this.nodes.has(id))
|
|
158
|
+
this.evictable.add(id);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
assertBranch(branch) {
|
|
162
|
+
if (!BRANCH_PATTERN.test(branch))
|
|
163
|
+
throw new RangeError(`branch must match ${BRANCH_PATTERN}`);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
6
167
|
// src/errors/error.ts
|
|
7
168
|
var CATEGORY_TO_SQLSTATE = {
|
|
8
169
|
syntax: "42601",
|
|
@@ -4201,7 +4362,13 @@ var RowScope = class {
|
|
|
4201
4362
|
}
|
|
4202
4363
|
};
|
|
4203
4364
|
function childEnv(env, outer) {
|
|
4204
|
-
return {
|
|
4365
|
+
return {
|
|
4366
|
+
ctx: env.ctx,
|
|
4367
|
+
params: env.params,
|
|
4368
|
+
ctes: env.ctes,
|
|
4369
|
+
outer,
|
|
4370
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
4371
|
+
};
|
|
4205
4372
|
}
|
|
4206
4373
|
function relationResult(rel2, command2) {
|
|
4207
4374
|
const visible = rel2.columns.map((c, i) => ({ i, c })).filter(({ c }) => !c.hidden);
|
|
@@ -8541,6 +8708,234 @@ function callScalarFunction(ctx, name, args2) {
|
|
|
8541
8708
|
return fn(ctx, args2);
|
|
8542
8709
|
}
|
|
8543
8710
|
|
|
8711
|
+
// src/functions/pgtrgm.ts
|
|
8712
|
+
var PGTRGM_BODY = "pg_trgm";
|
|
8713
|
+
var WORD_SIMILARITY_THRESHOLD = Math.fround(0.6);
|
|
8714
|
+
var GIN_TRGM_TYPES = /* @__PURE__ */ new Set(["text", "varchar"]);
|
|
8715
|
+
var WORD_CHAR = /[\p{L}\p{N}]+/gu;
|
|
8716
|
+
function pgTrgmSchema(state) {
|
|
8717
|
+
for (const schema of state.schemas.values()) {
|
|
8718
|
+
for (const fns of schema.functions.values()) {
|
|
8719
|
+
if (fns.some((fn) => fn.language === "internal" && fn.rawBody === PGTRGM_BODY)) return schema.name;
|
|
8720
|
+
}
|
|
8721
|
+
}
|
|
8722
|
+
return null;
|
|
8723
|
+
}
|
|
8724
|
+
function pgTrgmInstalled(state) {
|
|
8725
|
+
return pgTrgmSchema(state) !== null;
|
|
8726
|
+
}
|
|
8727
|
+
function installPgTrgm(state, schemaName) {
|
|
8728
|
+
const schema = state.getSchema(schemaName);
|
|
8729
|
+
const existing = schema.functions.get("similarity") ?? [];
|
|
8730
|
+
const fn = {
|
|
8731
|
+
name: "similarity",
|
|
8732
|
+
schema: schema.name,
|
|
8733
|
+
argNames: [null, null],
|
|
8734
|
+
argTypes: ["text", "text"],
|
|
8735
|
+
argDefaults: [null, null],
|
|
8736
|
+
returns: "float4",
|
|
8737
|
+
returnsSet: false,
|
|
8738
|
+
returnsTable: null,
|
|
8739
|
+
language: "internal",
|
|
8740
|
+
body: null,
|
|
8741
|
+
rawBody: PGTRGM_BODY,
|
|
8742
|
+
strict: true,
|
|
8743
|
+
oid: state.nextOid()
|
|
8744
|
+
};
|
|
8745
|
+
existing.push(fn);
|
|
8746
|
+
schema.functions.set("similarity", existing);
|
|
8747
|
+
}
|
|
8748
|
+
function uninstallPgTrgm(state) {
|
|
8749
|
+
let removed = false;
|
|
8750
|
+
for (const schema of state.schemas.values()) {
|
|
8751
|
+
for (const [name, fns] of [...schema.functions.entries()]) {
|
|
8752
|
+
const keep = fns.filter((fn) => fn.language !== "internal" || fn.rawBody !== PGTRGM_BODY);
|
|
8753
|
+
if (keep.length === fns.length) continue;
|
|
8754
|
+
removed = true;
|
|
8755
|
+
if (keep.length === 0) schema.functions.delete(name);
|
|
8756
|
+
else schema.functions.set(name, keep);
|
|
8757
|
+
}
|
|
8758
|
+
}
|
|
8759
|
+
return removed;
|
|
8760
|
+
}
|
|
8761
|
+
function evalPgTrgmFunction(ctx, fn, args2) {
|
|
8762
|
+
const ret = fn.returns ?? "float4";
|
|
8763
|
+
if (fn.strict && args2.some((arg) => arg.v === null)) return tv(ret, null);
|
|
8764
|
+
if (fn.name !== "similarity" || args2.length !== 2) {
|
|
8765
|
+
throw pgError("undefined_function", `function ${fn.schema}.${fn.name} is not implemented`, "42883");
|
|
8766
|
+
}
|
|
8767
|
+
const left = castTo(ctx, args2[0], "text");
|
|
8768
|
+
const right = castTo(ctx, args2[1], "text");
|
|
8769
|
+
if (left.v === null || right.v === null) return tv("float4", null);
|
|
8770
|
+
return tv("float4", trigramSimilarity(left.v, right.v));
|
|
8771
|
+
}
|
|
8772
|
+
function evalTrgmWordSimilar(ctx, left, right) {
|
|
8773
|
+
const missing = () => {
|
|
8774
|
+
throw pgError(
|
|
8775
|
+
"undefined_function",
|
|
8776
|
+
`operator does not exist: ${typeDisplayName(left.t)} <% ${typeDisplayName(right.t)}`
|
|
8777
|
+
);
|
|
8778
|
+
};
|
|
8779
|
+
if (!pgTrgmInstalled(ctx.state)) missing();
|
|
8780
|
+
if (!canImplicitCast(left.t, "text") || !canImplicitCast(right.t, "text")) missing();
|
|
8781
|
+
const a = castTo(ctx, left, "text");
|
|
8782
|
+
const b = castTo(ctx, right, "text");
|
|
8783
|
+
if (a.v === null || b.v === null) return tv("bool", null);
|
|
8784
|
+
const score = wordSimilarity(a.v, b.v);
|
|
8785
|
+
return tv("bool", score >= WORD_SIMILARITY_THRESHOLD);
|
|
8786
|
+
}
|
|
8787
|
+
function assertGinTrgmIndex(state, table, stmt) {
|
|
8788
|
+
const trgmCols = stmt.columns.filter((col2) => isGinTrgmOpclass(col2.opclass));
|
|
8789
|
+
if (trgmCols.length === 0) return;
|
|
8790
|
+
if (trgmCols.length !== stmt.columns.length || stmt.columns.length !== 1) {
|
|
8791
|
+
throw unsupported("multicolumn gin_trgm_ops");
|
|
8792
|
+
}
|
|
8793
|
+
const method = stmt.using ?? "btree";
|
|
8794
|
+
const col = trgmCols[0];
|
|
8795
|
+
const opclass = col.opclass;
|
|
8796
|
+
const label = opclass.join(".");
|
|
8797
|
+
if (method !== "gin" || !opclassVisible(state, opclass)) {
|
|
8798
|
+
throw pgError(
|
|
8799
|
+
"undefined_object",
|
|
8800
|
+
`operator class "${label}" does not exist for access method "${method}"`,
|
|
8801
|
+
"42704"
|
|
8802
|
+
);
|
|
8803
|
+
}
|
|
8804
|
+
if (stmt.unique) {
|
|
8805
|
+
throw pgError("feature_not_supported", `access method "gin" does not support unique indexes`, "0A000");
|
|
8806
|
+
}
|
|
8807
|
+
if (col.expr.type !== "colref" || col.expr.parts.length !== 1) {
|
|
8808
|
+
throw unsupported("expression gin_trgm_ops");
|
|
8809
|
+
}
|
|
8810
|
+
const index = table.columnIndex(col.expr.parts[0]);
|
|
8811
|
+
const typeId = table.columns[index].type.id;
|
|
8812
|
+
if (!GIN_TRGM_TYPES.has(typeId)) {
|
|
8813
|
+
throw pgError(
|
|
8814
|
+
"datatype_mismatch",
|
|
8815
|
+
`operator class "${label}" does not accept data type ${typeDisplayName(typeId)}`,
|
|
8816
|
+
"42804"
|
|
8817
|
+
);
|
|
8818
|
+
}
|
|
8819
|
+
}
|
|
8820
|
+
function isGinTrgmOpclass(opclass) {
|
|
8821
|
+
return opclass !== null && opclass[opclass.length - 1] === "gin_trgm_ops";
|
|
8822
|
+
}
|
|
8823
|
+
function opclassVisible(state, opclass) {
|
|
8824
|
+
const schema = pgTrgmSchema(state);
|
|
8825
|
+
if (schema === null || opclass[opclass.length - 1] !== "gin_trgm_ops") return false;
|
|
8826
|
+
if (opclass.length === 1) return state.effectiveSearchPath().includes(schema);
|
|
8827
|
+
if (opclass.length === 2) return opclass[0] === schema;
|
|
8828
|
+
return false;
|
|
8829
|
+
}
|
|
8830
|
+
function trigramSimilarity(left, right) {
|
|
8831
|
+
const a = uniqueSorted(orderedTrigrams(left));
|
|
8832
|
+
const b = uniqueSorted(orderedTrigrams(right));
|
|
8833
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
8834
|
+
let i = 0;
|
|
8835
|
+
let j = 0;
|
|
8836
|
+
let count = 0;
|
|
8837
|
+
while (i < a.length && j < b.length) {
|
|
8838
|
+
const cmp = a[i] < b[j] ? -1 : a[i] > b[j] ? 1 : 0;
|
|
8839
|
+
if (cmp < 0) i++;
|
|
8840
|
+
else if (cmp > 0) j++;
|
|
8841
|
+
else {
|
|
8842
|
+
count++;
|
|
8843
|
+
i++;
|
|
8844
|
+
j++;
|
|
8845
|
+
}
|
|
8846
|
+
}
|
|
8847
|
+
return calcSml(count, a.length, b.length);
|
|
8848
|
+
}
|
|
8849
|
+
function wordSimilarity(pattern, haystack) {
|
|
8850
|
+
const trg1 = orderedTrigrams(pattern);
|
|
8851
|
+
const trg2 = orderedTrigrams(haystack);
|
|
8852
|
+
const len1 = trg1.length;
|
|
8853
|
+
const len2 = trg2.length;
|
|
8854
|
+
if (len1 === 0 || len2 === 0) return 0;
|
|
8855
|
+
const positional = [];
|
|
8856
|
+
for (let i = 0; i < len1; i++) positional.push({ trg: trg1[i], index: -1 });
|
|
8857
|
+
for (let i = 0; i < len2; i++) positional.push({ trg: trg2[i], index: i });
|
|
8858
|
+
positional.sort((x, y) => x.trg < y.trg ? -1 : x.trg > y.trg ? 1 : x.index - y.index);
|
|
8859
|
+
const len = len1 + len2;
|
|
8860
|
+
const trg2indexes = new Array(len2);
|
|
8861
|
+
const found = new Array(len).fill(false);
|
|
8862
|
+
let ulen1 = 0;
|
|
8863
|
+
let group = 0;
|
|
8864
|
+
for (let i = 0; i < len; i++) {
|
|
8865
|
+
if (i > 0 && positional[i - 1].trg !== positional[i].trg) {
|
|
8866
|
+
if (found[group]) ulen1++;
|
|
8867
|
+
group++;
|
|
8868
|
+
}
|
|
8869
|
+
const index = positional[i].index;
|
|
8870
|
+
if (index >= 0) trg2indexes[index] = group;
|
|
8871
|
+
else found[group] = true;
|
|
8872
|
+
}
|
|
8873
|
+
if (found[group]) ulen1++;
|
|
8874
|
+
return iterateWordSimilarity(trg2indexes, found, ulen1, len2);
|
|
8875
|
+
}
|
|
8876
|
+
function orderedTrigrams(input) {
|
|
8877
|
+
const out = [];
|
|
8878
|
+
for (const match of input.matchAll(WORD_CHAR)) {
|
|
8879
|
+
const padded = ` ${match[0].toLowerCase()} `;
|
|
8880
|
+
for (let i = 0; i + 3 <= padded.length; i++) out.push(padded.slice(i, i + 3));
|
|
8881
|
+
}
|
|
8882
|
+
return out;
|
|
8883
|
+
}
|
|
8884
|
+
function uniqueSorted(trigrams) {
|
|
8885
|
+
return [...new Set(trigrams)].sort();
|
|
8886
|
+
}
|
|
8887
|
+
function calcSml(count, len1, len2) {
|
|
8888
|
+
const denom = len1 + len2 - count;
|
|
8889
|
+
if (denom <= 0) return 0;
|
|
8890
|
+
return Math.fround(count / denom);
|
|
8891
|
+
}
|
|
8892
|
+
function iterateWordSimilarity(trg2indexes, found, ulen1, len2) {
|
|
8893
|
+
const lastpos = new Array(found.length).fill(-1);
|
|
8894
|
+
let ulen2 = 0;
|
|
8895
|
+
let count = 0;
|
|
8896
|
+
let lower = -1;
|
|
8897
|
+
let smlrMax = 0;
|
|
8898
|
+
for (let i = 0; i < len2; i++) {
|
|
8899
|
+
const trgindex = trg2indexes[i];
|
|
8900
|
+
if (lower >= 0 || found[trgindex]) {
|
|
8901
|
+
if (lastpos[trgindex] < 0) {
|
|
8902
|
+
ulen2++;
|
|
8903
|
+
if (found[trgindex]) count++;
|
|
8904
|
+
}
|
|
8905
|
+
lastpos[trgindex] = i;
|
|
8906
|
+
}
|
|
8907
|
+
if (!found[trgindex]) continue;
|
|
8908
|
+
if (lower === -1) {
|
|
8909
|
+
lower = i;
|
|
8910
|
+
ulen2 = 1;
|
|
8911
|
+
}
|
|
8912
|
+
let smlrCur = calcSml(count, ulen1, ulen2);
|
|
8913
|
+
let tmpCount = count;
|
|
8914
|
+
let tmpUlen2 = ulen2;
|
|
8915
|
+
const prevLower = lower;
|
|
8916
|
+
for (let tmpLower = lower; tmpLower <= i; tmpLower++) {
|
|
8917
|
+
const smlrTmp = calcSml(tmpCount, ulen1, tmpUlen2);
|
|
8918
|
+
if (smlrTmp > smlrCur) {
|
|
8919
|
+
smlrCur = smlrTmp;
|
|
8920
|
+
ulen2 = tmpUlen2;
|
|
8921
|
+
lower = tmpLower;
|
|
8922
|
+
count = tmpCount;
|
|
8923
|
+
}
|
|
8924
|
+
const tmpTrgindex = trg2indexes[tmpLower];
|
|
8925
|
+
if (lastpos[tmpTrgindex] === tmpLower) {
|
|
8926
|
+
tmpUlen2--;
|
|
8927
|
+
if (found[tmpTrgindex]) tmpCount--;
|
|
8928
|
+
}
|
|
8929
|
+
}
|
|
8930
|
+
if (smlrCur > smlrMax) smlrMax = smlrCur;
|
|
8931
|
+
for (let tmpLower = prevLower; tmpLower < lower; tmpLower++) {
|
|
8932
|
+
const tmpTrgindex = trg2indexes[tmpLower];
|
|
8933
|
+
if (lastpos[tmpTrgindex] === tmpLower) lastpos[tmpTrgindex] = -1;
|
|
8934
|
+
}
|
|
8935
|
+
}
|
|
8936
|
+
return smlrMax;
|
|
8937
|
+
}
|
|
8938
|
+
|
|
8544
8939
|
// src/expressions/operators.ts
|
|
8545
8940
|
var NUM_LADDER = ["int2", "int4", "int8", "numeric", "float4", "float8"];
|
|
8546
8941
|
function opNotExist(op, l, r) {
|
|
@@ -8684,6 +9079,8 @@ function evalBinary(ctx, op, l0, r0) {
|
|
|
8684
9079
|
return evalJsonbDeletePath(ctx, l, r);
|
|
8685
9080
|
case "@@":
|
|
8686
9081
|
return evalTextSearchMatch(ctx, l, r);
|
|
9082
|
+
case "<%":
|
|
9083
|
+
return evalTrgmWordSimilar(ctx, l, r);
|
|
8687
9084
|
default:
|
|
8688
9085
|
opNotExist(op, l.t, r.t);
|
|
8689
9086
|
}
|
|
@@ -10904,6 +11301,634 @@ function unifyAggType(a, b) {
|
|
|
10904
11301
|
return unifyTypes(a, b) ?? a;
|
|
10905
11302
|
}
|
|
10906
11303
|
|
|
11304
|
+
// src/functions/pgcrypto.ts
|
|
11305
|
+
var PGCRYPTO_BODY = "pgcrypto";
|
|
11306
|
+
var utf82 = new TextEncoder();
|
|
11307
|
+
var MD5_S = [
|
|
11308
|
+
7,
|
|
11309
|
+
12,
|
|
11310
|
+
17,
|
|
11311
|
+
22,
|
|
11312
|
+
7,
|
|
11313
|
+
12,
|
|
11314
|
+
17,
|
|
11315
|
+
22,
|
|
11316
|
+
7,
|
|
11317
|
+
12,
|
|
11318
|
+
17,
|
|
11319
|
+
22,
|
|
11320
|
+
7,
|
|
11321
|
+
12,
|
|
11322
|
+
17,
|
|
11323
|
+
22,
|
|
11324
|
+
5,
|
|
11325
|
+
9,
|
|
11326
|
+
14,
|
|
11327
|
+
20,
|
|
11328
|
+
5,
|
|
11329
|
+
9,
|
|
11330
|
+
14,
|
|
11331
|
+
20,
|
|
11332
|
+
5,
|
|
11333
|
+
9,
|
|
11334
|
+
14,
|
|
11335
|
+
20,
|
|
11336
|
+
5,
|
|
11337
|
+
9,
|
|
11338
|
+
14,
|
|
11339
|
+
20,
|
|
11340
|
+
4,
|
|
11341
|
+
11,
|
|
11342
|
+
16,
|
|
11343
|
+
23,
|
|
11344
|
+
4,
|
|
11345
|
+
11,
|
|
11346
|
+
16,
|
|
11347
|
+
23,
|
|
11348
|
+
4,
|
|
11349
|
+
11,
|
|
11350
|
+
16,
|
|
11351
|
+
23,
|
|
11352
|
+
4,
|
|
11353
|
+
11,
|
|
11354
|
+
16,
|
|
11355
|
+
23,
|
|
11356
|
+
6,
|
|
11357
|
+
10,
|
|
11358
|
+
15,
|
|
11359
|
+
21,
|
|
11360
|
+
6,
|
|
11361
|
+
10,
|
|
11362
|
+
15,
|
|
11363
|
+
21,
|
|
11364
|
+
6,
|
|
11365
|
+
10,
|
|
11366
|
+
15,
|
|
11367
|
+
21,
|
|
11368
|
+
6,
|
|
11369
|
+
10,
|
|
11370
|
+
15,
|
|
11371
|
+
21
|
|
11372
|
+
];
|
|
11373
|
+
var MD5_K = new Uint32Array([
|
|
11374
|
+
3614090360,
|
|
11375
|
+
3905402710,
|
|
11376
|
+
606105819,
|
|
11377
|
+
3250441966,
|
|
11378
|
+
4118548399,
|
|
11379
|
+
1200080426,
|
|
11380
|
+
2821735955,
|
|
11381
|
+
4249261313,
|
|
11382
|
+
1770035416,
|
|
11383
|
+
2336552879,
|
|
11384
|
+
4294925233,
|
|
11385
|
+
2304563134,
|
|
11386
|
+
1804603682,
|
|
11387
|
+
4254626195,
|
|
11388
|
+
2792965006,
|
|
11389
|
+
1236535329,
|
|
11390
|
+
4129170786,
|
|
11391
|
+
3225465664,
|
|
11392
|
+
643717713,
|
|
11393
|
+
3921069994,
|
|
11394
|
+
3593408605,
|
|
11395
|
+
38016083,
|
|
11396
|
+
3634488961,
|
|
11397
|
+
3889429448,
|
|
11398
|
+
568446438,
|
|
11399
|
+
3275163606,
|
|
11400
|
+
4107603335,
|
|
11401
|
+
1163531501,
|
|
11402
|
+
2850285829,
|
|
11403
|
+
4243563512,
|
|
11404
|
+
1735328473,
|
|
11405
|
+
2368359562,
|
|
11406
|
+
4294588738,
|
|
11407
|
+
2272392833,
|
|
11408
|
+
1839030562,
|
|
11409
|
+
4259657740,
|
|
11410
|
+
2763975236,
|
|
11411
|
+
1272893353,
|
|
11412
|
+
4139469664,
|
|
11413
|
+
3200236656,
|
|
11414
|
+
681279174,
|
|
11415
|
+
3936430074,
|
|
11416
|
+
3572445317,
|
|
11417
|
+
76029189,
|
|
11418
|
+
3654602809,
|
|
11419
|
+
3873151461,
|
|
11420
|
+
530742520,
|
|
11421
|
+
3299628645,
|
|
11422
|
+
4096336452,
|
|
11423
|
+
1126891415,
|
|
11424
|
+
2878612391,
|
|
11425
|
+
4237533241,
|
|
11426
|
+
1700485571,
|
|
11427
|
+
2399980690,
|
|
11428
|
+
4293915773,
|
|
11429
|
+
2240044497,
|
|
11430
|
+
1873313359,
|
|
11431
|
+
4264355552,
|
|
11432
|
+
2734768916,
|
|
11433
|
+
1309151649,
|
|
11434
|
+
4149444226,
|
|
11435
|
+
3174756917,
|
|
11436
|
+
718787259,
|
|
11437
|
+
3951481745
|
|
11438
|
+
]);
|
|
11439
|
+
var SHA256_K = new Uint32Array([
|
|
11440
|
+
1116352408,
|
|
11441
|
+
1899447441,
|
|
11442
|
+
3049323471,
|
|
11443
|
+
3921009573,
|
|
11444
|
+
961987163,
|
|
11445
|
+
1508970993,
|
|
11446
|
+
2453635748,
|
|
11447
|
+
2870763221,
|
|
11448
|
+
3624381080,
|
|
11449
|
+
310598401,
|
|
11450
|
+
607225278,
|
|
11451
|
+
1426881987,
|
|
11452
|
+
1925078388,
|
|
11453
|
+
2162078206,
|
|
11454
|
+
2614888103,
|
|
11455
|
+
3248222580,
|
|
11456
|
+
3835390401,
|
|
11457
|
+
4022224774,
|
|
11458
|
+
264347078,
|
|
11459
|
+
604807628,
|
|
11460
|
+
770255983,
|
|
11461
|
+
1249150122,
|
|
11462
|
+
1555081692,
|
|
11463
|
+
1996064986,
|
|
11464
|
+
2554220882,
|
|
11465
|
+
2821834349,
|
|
11466
|
+
2952996808,
|
|
11467
|
+
3210313671,
|
|
11468
|
+
3336571891,
|
|
11469
|
+
3584528711,
|
|
11470
|
+
113926993,
|
|
11471
|
+
338241895,
|
|
11472
|
+
666307205,
|
|
11473
|
+
773529912,
|
|
11474
|
+
1294757372,
|
|
11475
|
+
1396182291,
|
|
11476
|
+
1695183700,
|
|
11477
|
+
1986661051,
|
|
11478
|
+
2177026350,
|
|
11479
|
+
2456956037,
|
|
11480
|
+
2730485921,
|
|
11481
|
+
2820302411,
|
|
11482
|
+
3259730800,
|
|
11483
|
+
3345764771,
|
|
11484
|
+
3516065817,
|
|
11485
|
+
3600352804,
|
|
11486
|
+
4094571909,
|
|
11487
|
+
275423344,
|
|
11488
|
+
430227734,
|
|
11489
|
+
506948616,
|
|
11490
|
+
659060556,
|
|
11491
|
+
883997877,
|
|
11492
|
+
958139571,
|
|
11493
|
+
1322822218,
|
|
11494
|
+
1537002063,
|
|
11495
|
+
1747873779,
|
|
11496
|
+
1955562222,
|
|
11497
|
+
2024104815,
|
|
11498
|
+
2227730452,
|
|
11499
|
+
2361852424,
|
|
11500
|
+
2428436474,
|
|
11501
|
+
2756734187,
|
|
11502
|
+
3204031479,
|
|
11503
|
+
3329325298
|
|
11504
|
+
]);
|
|
11505
|
+
var SHA512_K = [
|
|
11506
|
+
0x428a2f98d728ae22n,
|
|
11507
|
+
0x7137449123ef65cdn,
|
|
11508
|
+
0xb5c0fbcfec4d3b2fn,
|
|
11509
|
+
0xe9b5dba58189dbbcn,
|
|
11510
|
+
0x3956c25bf348b538n,
|
|
11511
|
+
0x59f111f1b605d019n,
|
|
11512
|
+
0x923f82a4af194f9bn,
|
|
11513
|
+
0xab1c5ed5da6d8118n,
|
|
11514
|
+
0xd807aa98a3030242n,
|
|
11515
|
+
0x12835b0145706fben,
|
|
11516
|
+
0x243185be4ee4b28cn,
|
|
11517
|
+
0x550c7dc3d5ffb4e2n,
|
|
11518
|
+
0x72be5d74f27b896fn,
|
|
11519
|
+
0x80deb1fe3b1696b1n,
|
|
11520
|
+
0x9bdc06a725c71235n,
|
|
11521
|
+
0xc19bf174cf692694n,
|
|
11522
|
+
0xe49b69c19ef14ad2n,
|
|
11523
|
+
0xefbe4786384f25e3n,
|
|
11524
|
+
0x0fc19dc68b8cd5b5n,
|
|
11525
|
+
0x240ca1cc77ac9c65n,
|
|
11526
|
+
0x2de92c6f592b0275n,
|
|
11527
|
+
0x4a7484aa6ea6e483n,
|
|
11528
|
+
0x5cb0a9dcbd41fbd4n,
|
|
11529
|
+
0x76f988da831153b5n,
|
|
11530
|
+
0x983e5152ee66dfabn,
|
|
11531
|
+
0xa831c66d2db43210n,
|
|
11532
|
+
0xb00327c898fb213fn,
|
|
11533
|
+
0xbf597fc7beef0ee4n,
|
|
11534
|
+
0xc6e00bf33da88fc2n,
|
|
11535
|
+
0xd5a79147930aa725n,
|
|
11536
|
+
0x06ca6351e003826fn,
|
|
11537
|
+
0x142929670a0e6e70n,
|
|
11538
|
+
0x27b70a8546d22ffcn,
|
|
11539
|
+
0x2e1b21385c26c926n,
|
|
11540
|
+
0x4d2c6dfc5ac42aedn,
|
|
11541
|
+
0x53380d139d95b3dfn,
|
|
11542
|
+
0x650a73548baf63den,
|
|
11543
|
+
0x766a0abb3c77b2a8n,
|
|
11544
|
+
0x81c2c92e47edaee6n,
|
|
11545
|
+
0x92722c851482353bn,
|
|
11546
|
+
0xa2bfe8a14cf10364n,
|
|
11547
|
+
0xa81a664bbc423001n,
|
|
11548
|
+
0xc24b8b70d0f89791n,
|
|
11549
|
+
0xc76c51a30654be30n,
|
|
11550
|
+
0xd192e819d6ef5218n,
|
|
11551
|
+
0xd69906245565a910n,
|
|
11552
|
+
0xf40e35855771202an,
|
|
11553
|
+
0x106aa07032bbd1b8n,
|
|
11554
|
+
0x19a4c116b8d2d0c8n,
|
|
11555
|
+
0x1e376c085141ab53n,
|
|
11556
|
+
0x2748774cdf8eeb99n,
|
|
11557
|
+
0x34b0bcb5e19b48a8n,
|
|
11558
|
+
0x391c0cb3c5c95a63n,
|
|
11559
|
+
0x4ed8aa4ae3418acbn,
|
|
11560
|
+
0x5b9cca4f7763e373n,
|
|
11561
|
+
0x682e6ff3d6b2b8a3n,
|
|
11562
|
+
0x748f82ee5defb2fcn,
|
|
11563
|
+
0x78a5636f43172f60n,
|
|
11564
|
+
0x84c87814a1f0ab72n,
|
|
11565
|
+
0x8cc702081a6439ecn,
|
|
11566
|
+
0x90befffa23631e28n,
|
|
11567
|
+
0xa4506cebde82bde9n,
|
|
11568
|
+
0xbef9a3f7b2c67915n,
|
|
11569
|
+
0xc67178f2e372532bn,
|
|
11570
|
+
0xca273eceea26619cn,
|
|
11571
|
+
0xd186b8c721c0c207n,
|
|
11572
|
+
0xeada7dd6cde0eb1en,
|
|
11573
|
+
0xf57d4f7fee6ed178n,
|
|
11574
|
+
0x06f067aa72176fban,
|
|
11575
|
+
0x0a637dc5a2c898a6n,
|
|
11576
|
+
0x113f9804bef90daen,
|
|
11577
|
+
0x1b710b35131c471bn,
|
|
11578
|
+
0x28db77f523047d84n,
|
|
11579
|
+
0x32caab7b40c72493n,
|
|
11580
|
+
0x3c9ebe0a15c9bebcn,
|
|
11581
|
+
0x431d67c49c100d4cn,
|
|
11582
|
+
0x4cc5d4becb3e42b6n,
|
|
11583
|
+
0x597f299cfc657e2an,
|
|
11584
|
+
0x5fcb6fab3ad6faecn,
|
|
11585
|
+
0x6c44198c4a475817n
|
|
11586
|
+
];
|
|
11587
|
+
var MASK64 = (1n << 64n) - 1n;
|
|
11588
|
+
function rotl32(x, n) {
|
|
11589
|
+
return (x << n | x >>> 32 - n) >>> 0;
|
|
11590
|
+
}
|
|
11591
|
+
function rotr32(x, n) {
|
|
11592
|
+
return (x >>> n | x << 32 - n) >>> 0;
|
|
11593
|
+
}
|
|
11594
|
+
function rotr64(x, n) {
|
|
11595
|
+
return (x >> n | x << 64n - n) & MASK64;
|
|
11596
|
+
}
|
|
11597
|
+
function padBe(data, block, lengthBytes) {
|
|
11598
|
+
const bitLen = BigInt(data.length) * 8n;
|
|
11599
|
+
let len = data.length + 1 + lengthBytes;
|
|
11600
|
+
const rem = len % block;
|
|
11601
|
+
if (rem !== 0) len += block - rem;
|
|
11602
|
+
const out = new Uint8Array(len);
|
|
11603
|
+
out.set(data);
|
|
11604
|
+
out[data.length] = 128;
|
|
11605
|
+
const view = new DataView(out.buffer);
|
|
11606
|
+
view.setUint32(out.length - 8, Number(bitLen >> 32n & 0xffffffffn), false);
|
|
11607
|
+
view.setUint32(out.length - 4, Number(bitLen & 0xffffffffn), false);
|
|
11608
|
+
return out;
|
|
11609
|
+
}
|
|
11610
|
+
function padMd5(data) {
|
|
11611
|
+
const bitLen = BigInt(data.length) * 8n;
|
|
11612
|
+
let len = data.length + 1 + 8;
|
|
11613
|
+
const rem = len % 64;
|
|
11614
|
+
if (rem !== 0) len += 64 - rem;
|
|
11615
|
+
const out = new Uint8Array(len);
|
|
11616
|
+
out.set(data);
|
|
11617
|
+
out[data.length] = 128;
|
|
11618
|
+
const view = new DataView(out.buffer);
|
|
11619
|
+
view.setUint32(out.length - 8, Number(bitLen & 0xffffffffn), true);
|
|
11620
|
+
view.setUint32(out.length - 4, Number(bitLen >> 32n & 0xffffffffn), true);
|
|
11621
|
+
return out;
|
|
11622
|
+
}
|
|
11623
|
+
function md5(data) {
|
|
11624
|
+
const bytes = padMd5(data);
|
|
11625
|
+
const view = new DataView(bytes.buffer);
|
|
11626
|
+
let a0 = 1732584193;
|
|
11627
|
+
let b0 = 4023233417;
|
|
11628
|
+
let c0 = 2562383102;
|
|
11629
|
+
let d0 = 271733878;
|
|
11630
|
+
const m = new Uint32Array(16);
|
|
11631
|
+
for (let off = 0; off < bytes.length; off += 64) {
|
|
11632
|
+
for (let i = 0; i < 16; i++) m[i] = view.getUint32(off + i * 4, true);
|
|
11633
|
+
let a = a0;
|
|
11634
|
+
let b = b0;
|
|
11635
|
+
let c = c0;
|
|
11636
|
+
let d = d0;
|
|
11637
|
+
for (let i = 0; i < 64; i++) {
|
|
11638
|
+
let f;
|
|
11639
|
+
let g;
|
|
11640
|
+
if (i < 16) {
|
|
11641
|
+
f = b & c | ~b & d;
|
|
11642
|
+
g = i;
|
|
11643
|
+
} else if (i < 32) {
|
|
11644
|
+
f = d & b | ~d & c;
|
|
11645
|
+
g = (5 * i + 1) % 16;
|
|
11646
|
+
} else if (i < 48) {
|
|
11647
|
+
f = b ^ c ^ d;
|
|
11648
|
+
g = (3 * i + 5) % 16;
|
|
11649
|
+
} else {
|
|
11650
|
+
f = c ^ (b | ~d);
|
|
11651
|
+
g = 7 * i % 16;
|
|
11652
|
+
}
|
|
11653
|
+
const sum = f + a + MD5_K[i] + m[g] >>> 0;
|
|
11654
|
+
a = d;
|
|
11655
|
+
d = c;
|
|
11656
|
+
c = b;
|
|
11657
|
+
b = b + rotl32(sum, MD5_S[i]) >>> 0;
|
|
11658
|
+
}
|
|
11659
|
+
a0 = a0 + a >>> 0;
|
|
11660
|
+
b0 = b0 + b >>> 0;
|
|
11661
|
+
c0 = c0 + c >>> 0;
|
|
11662
|
+
d0 = d0 + d >>> 0;
|
|
11663
|
+
}
|
|
11664
|
+
const out = new Uint8Array(16);
|
|
11665
|
+
const ov = new DataView(out.buffer);
|
|
11666
|
+
ov.setUint32(0, a0, true);
|
|
11667
|
+
ov.setUint32(4, b0, true);
|
|
11668
|
+
ov.setUint32(8, c0, true);
|
|
11669
|
+
ov.setUint32(12, d0, true);
|
|
11670
|
+
return out;
|
|
11671
|
+
}
|
|
11672
|
+
function sha1(data) {
|
|
11673
|
+
const bytes = padBe(data, 64, 8);
|
|
11674
|
+
const view = new DataView(bytes.buffer);
|
|
11675
|
+
let h0 = 1732584193;
|
|
11676
|
+
let h1 = 4023233417;
|
|
11677
|
+
let h2 = 2562383102;
|
|
11678
|
+
let h3 = 271733878;
|
|
11679
|
+
let h4 = 3285377520;
|
|
11680
|
+
const w = new Uint32Array(80);
|
|
11681
|
+
for (let off = 0; off < bytes.length; off += 64) {
|
|
11682
|
+
for (let t = 0; t < 16; t++) w[t] = view.getUint32(off + t * 4, false);
|
|
11683
|
+
for (let t = 16; t < 80; t++) w[t] = rotl32(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1);
|
|
11684
|
+
let a = h0;
|
|
11685
|
+
let b = h1;
|
|
11686
|
+
let c = h2;
|
|
11687
|
+
let d = h3;
|
|
11688
|
+
let e = h4;
|
|
11689
|
+
for (let t = 0; t < 80; t++) {
|
|
11690
|
+
let f;
|
|
11691
|
+
let k;
|
|
11692
|
+
if (t < 20) {
|
|
11693
|
+
f = b & c | ~b & d;
|
|
11694
|
+
k = 1518500249;
|
|
11695
|
+
} else if (t < 40) {
|
|
11696
|
+
f = b ^ c ^ d;
|
|
11697
|
+
k = 1859775393;
|
|
11698
|
+
} else if (t < 60) {
|
|
11699
|
+
f = b & c | b & d | c & d;
|
|
11700
|
+
k = 2400959708;
|
|
11701
|
+
} else {
|
|
11702
|
+
f = b ^ c ^ d;
|
|
11703
|
+
k = 3395469782;
|
|
11704
|
+
}
|
|
11705
|
+
const temp = rotl32(a, 5) + f + e + k + w[t] >>> 0;
|
|
11706
|
+
e = d;
|
|
11707
|
+
d = c;
|
|
11708
|
+
c = rotl32(b, 30);
|
|
11709
|
+
b = a;
|
|
11710
|
+
a = temp;
|
|
11711
|
+
}
|
|
11712
|
+
h0 = h0 + a >>> 0;
|
|
11713
|
+
h1 = h1 + b >>> 0;
|
|
11714
|
+
h2 = h2 + c >>> 0;
|
|
11715
|
+
h3 = h3 + d >>> 0;
|
|
11716
|
+
h4 = h4 + e >>> 0;
|
|
11717
|
+
}
|
|
11718
|
+
const out = new Uint8Array(20);
|
|
11719
|
+
const ov = new DataView(out.buffer);
|
|
11720
|
+
ov.setUint32(0, h0, false);
|
|
11721
|
+
ov.setUint32(4, h1, false);
|
|
11722
|
+
ov.setUint32(8, h2, false);
|
|
11723
|
+
ov.setUint32(12, h3, false);
|
|
11724
|
+
ov.setUint32(16, h4, false);
|
|
11725
|
+
return out;
|
|
11726
|
+
}
|
|
11727
|
+
function sha256(data, sha224) {
|
|
11728
|
+
const bytes = padBe(data, 64, 8);
|
|
11729
|
+
const view = new DataView(bytes.buffer);
|
|
11730
|
+
let h0 = sha224 ? 3238371032 : 1779033703;
|
|
11731
|
+
let h1 = sha224 ? 914150663 : 3144134277;
|
|
11732
|
+
let h2 = sha224 ? 812702999 : 1013904242;
|
|
11733
|
+
let h3 = sha224 ? 4144912697 : 2773480762;
|
|
11734
|
+
let h4 = sha224 ? 4290775857 : 1359893119;
|
|
11735
|
+
let h5 = sha224 ? 1750603025 : 2600822924;
|
|
11736
|
+
let h6 = sha224 ? 1694076839 : 528734635;
|
|
11737
|
+
let h7 = sha224 ? 3204075428 : 1541459225;
|
|
11738
|
+
const w = new Uint32Array(64);
|
|
11739
|
+
for (let off = 0; off < bytes.length; off += 64) {
|
|
11740
|
+
for (let t = 0; t < 16; t++) w[t] = view.getUint32(off + t * 4, false);
|
|
11741
|
+
for (let t = 16; t < 64; t++) {
|
|
11742
|
+
const x15 = w[t - 15];
|
|
11743
|
+
const x2 = w[t - 2];
|
|
11744
|
+
const s0 = rotr32(x15, 7) ^ rotr32(x15, 18) ^ x15 >>> 3;
|
|
11745
|
+
const s1 = rotr32(x2, 17) ^ rotr32(x2, 19) ^ x2 >>> 10;
|
|
11746
|
+
w[t] = w[t - 16] + s0 + w[t - 7] + s1 >>> 0;
|
|
11747
|
+
}
|
|
11748
|
+
let a = h0;
|
|
11749
|
+
let b = h1;
|
|
11750
|
+
let c = h2;
|
|
11751
|
+
let d = h3;
|
|
11752
|
+
let e = h4;
|
|
11753
|
+
let f = h5;
|
|
11754
|
+
let g = h6;
|
|
11755
|
+
let h = h7;
|
|
11756
|
+
for (let t = 0; t < 64; t++) {
|
|
11757
|
+
const s1 = rotr32(e, 6) ^ rotr32(e, 11) ^ rotr32(e, 25);
|
|
11758
|
+
const ch = e & f ^ ~e & g;
|
|
11759
|
+
const t1 = h + s1 + ch + SHA256_K[t] + w[t] >>> 0;
|
|
11760
|
+
const s0 = rotr32(a, 2) ^ rotr32(a, 13) ^ rotr32(a, 22);
|
|
11761
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
11762
|
+
const t2 = s0 + maj >>> 0;
|
|
11763
|
+
h = g;
|
|
11764
|
+
g = f;
|
|
11765
|
+
f = e;
|
|
11766
|
+
e = d + t1 >>> 0;
|
|
11767
|
+
d = c;
|
|
11768
|
+
c = b;
|
|
11769
|
+
b = a;
|
|
11770
|
+
a = t1 + t2 >>> 0;
|
|
11771
|
+
}
|
|
11772
|
+
h0 = h0 + a >>> 0;
|
|
11773
|
+
h1 = h1 + b >>> 0;
|
|
11774
|
+
h2 = h2 + c >>> 0;
|
|
11775
|
+
h3 = h3 + d >>> 0;
|
|
11776
|
+
h4 = h4 + e >>> 0;
|
|
11777
|
+
h5 = h5 + f >>> 0;
|
|
11778
|
+
h6 = h6 + g >>> 0;
|
|
11779
|
+
h7 = h7 + h >>> 0;
|
|
11780
|
+
}
|
|
11781
|
+
const words = sha224 ? 7 : 8;
|
|
11782
|
+
const out = new Uint8Array(words * 4);
|
|
11783
|
+
const ov = new DataView(out.buffer);
|
|
11784
|
+
const hs = [h0, h1, h2, h3, h4, h5, h6, h7];
|
|
11785
|
+
for (let i = 0; i < words; i++) ov.setUint32(i * 4, hs[i], false);
|
|
11786
|
+
return out;
|
|
11787
|
+
}
|
|
11788
|
+
function readUint64BE(view, offset) {
|
|
11789
|
+
return BigInt(view.getUint32(offset, false)) << 32n | BigInt(view.getUint32(offset + 4, false));
|
|
11790
|
+
}
|
|
11791
|
+
function sha512(data, sha384) {
|
|
11792
|
+
const bytes = padBe(data, 128, 16);
|
|
11793
|
+
const view = new DataView(bytes.buffer);
|
|
11794
|
+
let h0 = sha384 ? 0xcbbb9d5dc1059ed8n : 0x6a09e667f3bcc908n;
|
|
11795
|
+
let h1 = sha384 ? 0x629a292a367cd507n : 0xbb67ae8584caa73bn;
|
|
11796
|
+
let h2 = sha384 ? 0x9159015a3070dd17n : 0x3c6ef372fe94f82bn;
|
|
11797
|
+
let h3 = sha384 ? 0x152fecd8f70e5939n : 0xa54ff53a5f1d36f1n;
|
|
11798
|
+
let h4 = sha384 ? 0x67332667ffc00b31n : 0x510e527fade682d1n;
|
|
11799
|
+
let h5 = sha384 ? 0x8eb44a8768581511n : 0x9b05688c2b3e6c1fn;
|
|
11800
|
+
let h6 = sha384 ? 0xdb0c2e0d64f98fa7n : 0x1f83d9abfb41bd6bn;
|
|
11801
|
+
let h7 = sha384 ? 0x47b5481dbefa4fa4n : 0x5be0cd19137e2179n;
|
|
11802
|
+
const w = new Array(80);
|
|
11803
|
+
for (let off = 0; off < bytes.length; off += 128) {
|
|
11804
|
+
for (let t = 0; t < 16; t++) w[t] = readUint64BE(view, off + t * 8);
|
|
11805
|
+
for (let t = 16; t < 80; t++) {
|
|
11806
|
+
const x15 = w[t - 15];
|
|
11807
|
+
const x2 = w[t - 2];
|
|
11808
|
+
const s0 = rotr64(x15, 1n) ^ rotr64(x15, 8n) ^ x15 >> 7n;
|
|
11809
|
+
const s1 = rotr64(x2, 19n) ^ rotr64(x2, 61n) ^ x2 >> 6n;
|
|
11810
|
+
w[t] = w[t - 16] + s0 + w[t - 7] + s1 & MASK64;
|
|
11811
|
+
}
|
|
11812
|
+
let a = h0;
|
|
11813
|
+
let b = h1;
|
|
11814
|
+
let c = h2;
|
|
11815
|
+
let d = h3;
|
|
11816
|
+
let e = h4;
|
|
11817
|
+
let f = h5;
|
|
11818
|
+
let g = h6;
|
|
11819
|
+
let h = h7;
|
|
11820
|
+
for (let t = 0; t < 80; t++) {
|
|
11821
|
+
const s1 = rotr64(e, 14n) ^ rotr64(e, 18n) ^ rotr64(e, 41n);
|
|
11822
|
+
const ch = e & f ^ ~e & g & MASK64;
|
|
11823
|
+
const t1 = h + s1 + ch + SHA512_K[t] + w[t] & MASK64;
|
|
11824
|
+
const s0 = rotr64(a, 28n) ^ rotr64(a, 34n) ^ rotr64(a, 39n);
|
|
11825
|
+
const maj = a & b ^ a & c ^ b & c;
|
|
11826
|
+
const t2 = s0 + maj & MASK64;
|
|
11827
|
+
h = g;
|
|
11828
|
+
g = f;
|
|
11829
|
+
f = e;
|
|
11830
|
+
e = d + t1 & MASK64;
|
|
11831
|
+
d = c;
|
|
11832
|
+
c = b;
|
|
11833
|
+
b = a;
|
|
11834
|
+
a = t1 + t2 & MASK64;
|
|
11835
|
+
}
|
|
11836
|
+
h0 = h0 + a & MASK64;
|
|
11837
|
+
h1 = h1 + b & MASK64;
|
|
11838
|
+
h2 = h2 + c & MASK64;
|
|
11839
|
+
h3 = h3 + d & MASK64;
|
|
11840
|
+
h4 = h4 + e & MASK64;
|
|
11841
|
+
h5 = h5 + f & MASK64;
|
|
11842
|
+
h6 = h6 + g & MASK64;
|
|
11843
|
+
h7 = h7 + h & MASK64;
|
|
11844
|
+
}
|
|
11845
|
+
const words = sha384 ? 6 : 8;
|
|
11846
|
+
const out = new Uint8Array(words * 8);
|
|
11847
|
+
const ov = new DataView(out.buffer);
|
|
11848
|
+
const hs = [h0, h1, h2, h3, h4, h5, h6, h7];
|
|
11849
|
+
for (let i = 0; i < words; i++) {
|
|
11850
|
+
const word = hs[i];
|
|
11851
|
+
ov.setUint32(i * 8, Number(word >> 32n & 0xffffffffn), false);
|
|
11852
|
+
ov.setUint32(i * 8 + 4, Number(word & 0xffffffffn), false);
|
|
11853
|
+
}
|
|
11854
|
+
return out;
|
|
11855
|
+
}
|
|
11856
|
+
function digestBytes(data, algorithm) {
|
|
11857
|
+
switch (algorithm.toLowerCase().replaceAll("-", "")) {
|
|
11858
|
+
case "md5":
|
|
11859
|
+
return md5(data);
|
|
11860
|
+
case "sha1":
|
|
11861
|
+
return sha1(data);
|
|
11862
|
+
case "sha224":
|
|
11863
|
+
return sha256(data, true);
|
|
11864
|
+
case "sha256":
|
|
11865
|
+
return sha256(data, false);
|
|
11866
|
+
case "sha384":
|
|
11867
|
+
return sha512(data, true);
|
|
11868
|
+
case "sha512":
|
|
11869
|
+
return sha512(data, false);
|
|
11870
|
+
default:
|
|
11871
|
+
throw pgError("invalid_parameter_value", `Cannot use "${algorithm}": No such hash algorithm`, "22023");
|
|
11872
|
+
}
|
|
11873
|
+
}
|
|
11874
|
+
function pgcryptoInstalled(state) {
|
|
11875
|
+
for (const schema of state.schemas.values()) {
|
|
11876
|
+
for (const fns of schema.functions.values()) {
|
|
11877
|
+
if (fns.some((fn) => fn.language === "internal" && fn.rawBody === PGCRYPTO_BODY)) return true;
|
|
11878
|
+
}
|
|
11879
|
+
}
|
|
11880
|
+
return false;
|
|
11881
|
+
}
|
|
11882
|
+
function installPgcrypto(state, schemaName) {
|
|
11883
|
+
const schema = state.getSchema(schemaName);
|
|
11884
|
+
const existing = schema.functions.get("digest") ?? [];
|
|
11885
|
+
const arg0Types = ["text", "bytea"];
|
|
11886
|
+
for (const arg0 of arg0Types) {
|
|
11887
|
+
const fn = {
|
|
11888
|
+
name: "digest",
|
|
11889
|
+
schema: schema.name,
|
|
11890
|
+
argNames: [null, null],
|
|
11891
|
+
argTypes: [arg0, "text"],
|
|
11892
|
+
argDefaults: [null, null],
|
|
11893
|
+
returns: "bytea",
|
|
11894
|
+
returnsSet: false,
|
|
11895
|
+
returnsTable: null,
|
|
11896
|
+
language: "internal",
|
|
11897
|
+
body: null,
|
|
11898
|
+
rawBody: PGCRYPTO_BODY,
|
|
11899
|
+
strict: true,
|
|
11900
|
+
oid: state.nextOid()
|
|
11901
|
+
};
|
|
11902
|
+
existing.push(fn);
|
|
11903
|
+
}
|
|
11904
|
+
schema.functions.set("digest", existing);
|
|
11905
|
+
}
|
|
11906
|
+
function uninstallPgcrypto(state) {
|
|
11907
|
+
let removed = false;
|
|
11908
|
+
for (const schema of state.schemas.values()) {
|
|
11909
|
+
for (const [name, fns] of [...schema.functions.entries()]) {
|
|
11910
|
+
const keep = fns.filter((fn) => fn.language !== "internal" || fn.rawBody !== PGCRYPTO_BODY);
|
|
11911
|
+
if (keep.length === fns.length) continue;
|
|
11912
|
+
removed = true;
|
|
11913
|
+
if (keep.length === 0) schema.functions.delete(name);
|
|
11914
|
+
else schema.functions.set(name, keep);
|
|
11915
|
+
}
|
|
11916
|
+
}
|
|
11917
|
+
return removed;
|
|
11918
|
+
}
|
|
11919
|
+
function evalPgcryptoFunction(ctx, fn, args2) {
|
|
11920
|
+
const ret = fn.returns ?? "bytea";
|
|
11921
|
+
if (fn.strict && args2.some((arg) => arg.v === null)) return tv(ret, null);
|
|
11922
|
+
if (fn.name !== "digest" || args2.length !== 2) {
|
|
11923
|
+
throw pgError("undefined_function", `function ${fn.schema}.${fn.name} is not implemented`, "42883");
|
|
11924
|
+
}
|
|
11925
|
+
const data = castTo(ctx, args2[0], fn.argTypes[0] ?? "bytea", {});
|
|
11926
|
+
const algorithm = castTo(ctx, args2[1], "text", {});
|
|
11927
|
+
if (data.v === null || algorithm.v === null) return tv("bytea", null);
|
|
11928
|
+
const bytes = fn.argTypes[0] === "bytea" ? data.v : utf82.encode(data.v);
|
|
11929
|
+
return tv("bytea", digestBytes(bytes, algorithm.v));
|
|
11930
|
+
}
|
|
11931
|
+
|
|
10907
11932
|
// src/functions/srf.ts
|
|
10908
11933
|
function jsonInput(ctx, a) {
|
|
10909
11934
|
void ctx;
|
|
@@ -13097,10 +14122,32 @@ var Parser = class {
|
|
|
13097
14122
|
}
|
|
13098
14123
|
if (this.atKw("extension")) {
|
|
13099
14124
|
this.pos++;
|
|
13100
|
-
this.parseIfNotExists();
|
|
14125
|
+
const ifNotExists = this.parseIfNotExists();
|
|
13101
14126
|
const name = this.ident(true);
|
|
13102
|
-
|
|
13103
|
-
|
|
14127
|
+
let schema = null;
|
|
14128
|
+
let version = null;
|
|
14129
|
+
let cascade = false;
|
|
14130
|
+
this.eatKw("with");
|
|
14131
|
+
while (!this.atPunct(";") && this.peek().type !== "eof") {
|
|
14132
|
+
if (this.eatKw("schema")) {
|
|
14133
|
+
schema = this.ident(true);
|
|
14134
|
+
continue;
|
|
14135
|
+
}
|
|
14136
|
+
if (this.eatKw("version")) {
|
|
14137
|
+
const token = this.next();
|
|
14138
|
+
if (token.type !== "string" && token.type !== "ident" && token.type !== "quoted_ident") {
|
|
14139
|
+
this.errorAt(token, "expected extension version");
|
|
14140
|
+
}
|
|
14141
|
+
version = token.value;
|
|
14142
|
+
continue;
|
|
14143
|
+
}
|
|
14144
|
+
if (this.eatKw("cascade")) {
|
|
14145
|
+
cascade = true;
|
|
14146
|
+
continue;
|
|
14147
|
+
}
|
|
14148
|
+
throw unsupported("CREATE EXTENSION option");
|
|
14149
|
+
}
|
|
14150
|
+
return { type: "create_extension", name, ifNotExists, schema, version, cascade };
|
|
13104
14151
|
}
|
|
13105
14152
|
if (this.atKw("database")) throw unsupported("CREATE DATABASE");
|
|
13106
14153
|
if (this.atKw("role") || this.atKw("user") || this.atKw("group")) throw unsupported("roles");
|
|
@@ -13577,7 +14624,11 @@ var Parser = class {
|
|
|
13577
14624
|
let opclass = null;
|
|
13578
14625
|
const t = this.peek();
|
|
13579
14626
|
if (t.type === "ident" && !RESERVED.has(t.value) && !["asc", "desc", "nulls", "with", "where", "include"].includes(t.value)) {
|
|
13580
|
-
opclass = this.ident();
|
|
14627
|
+
opclass = [this.ident()];
|
|
14628
|
+
while (this.atPunct(".")) {
|
|
14629
|
+
this.pos++;
|
|
14630
|
+
opclass.push(this.ident(true));
|
|
14631
|
+
}
|
|
13581
14632
|
}
|
|
13582
14633
|
let dir = null;
|
|
13583
14634
|
if (this.eatKw("asc")) dir = "asc";
|
|
@@ -15813,7 +16864,13 @@ function runStmt(env, stmt, vars, emit, tableNames) {
|
|
|
15813
16864
|
return;
|
|
15814
16865
|
}
|
|
15815
16866
|
case "for": {
|
|
15816
|
-
const forEnv = {
|
|
16867
|
+
const forEnv = {
|
|
16868
|
+
ctx: env.ctx,
|
|
16869
|
+
params: env.params,
|
|
16870
|
+
ctes: env.ctes,
|
|
16871
|
+
outer: vars.scope(),
|
|
16872
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
16873
|
+
};
|
|
15817
16874
|
const rel2 = executeSelectStmt(forEnv, stmt.query);
|
|
15818
16875
|
for (const row of rel2.rows) {
|
|
15819
16876
|
for (let i = 0; i < stmt.targets.length; i++) {
|
|
@@ -15855,7 +16912,13 @@ function initVars(env, fn, bound, program) {
|
|
|
15855
16912
|
if (fn.returnsTable) {
|
|
15856
16913
|
for (const c of fn.returnsTable) vars.declare(c.name, c.type, null);
|
|
15857
16914
|
}
|
|
15858
|
-
const seed = () => ({
|
|
16915
|
+
const seed = () => ({
|
|
16916
|
+
ctx: env.ctx,
|
|
16917
|
+
params: bound,
|
|
16918
|
+
ctes: /* @__PURE__ */ new Map(),
|
|
16919
|
+
outer: vars.scope(),
|
|
16920
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
16921
|
+
});
|
|
15859
16922
|
for (const d of program.decls) {
|
|
15860
16923
|
const id = resolveTypeName(env.ctx.state, d.typeName).column.id;
|
|
15861
16924
|
let val = null;
|
|
@@ -15868,7 +16931,13 @@ function initVars(env, fn, bound, program) {
|
|
|
15868
16931
|
return vars;
|
|
15869
16932
|
}
|
|
15870
16933
|
function plpgsqlEnv(env, bound, vars) {
|
|
15871
|
-
return {
|
|
16934
|
+
return {
|
|
16935
|
+
ctx: env.ctx,
|
|
16936
|
+
params: bound,
|
|
16937
|
+
ctes: /* @__PURE__ */ new Map(),
|
|
16938
|
+
outer: vars.scope(),
|
|
16939
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
16940
|
+
};
|
|
15872
16941
|
}
|
|
15873
16942
|
function callPlpgsqlScalar(env, fn, args2) {
|
|
15874
16943
|
const retT = fn.returns ?? "text";
|
|
@@ -16467,7 +17536,13 @@ function functionEnv(env, fn, args2) {
|
|
|
16467
17536
|
bound.push(castTo(env.ctx, evalScalar(env, null, dflt), fn.argTypes[i], {}));
|
|
16468
17537
|
}
|
|
16469
17538
|
}
|
|
16470
|
-
const fnEnv = {
|
|
17539
|
+
const fnEnv = {
|
|
17540
|
+
ctx: env.ctx,
|
|
17541
|
+
params: bound,
|
|
17542
|
+
ctes: /* @__PURE__ */ new Map(),
|
|
17543
|
+
outer: null,
|
|
17544
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
17545
|
+
};
|
|
16471
17546
|
const namedCols = fn.argNames.map((n, i) => ({ n, i })).filter((x) => x.n !== null);
|
|
16472
17547
|
if (namedCols.length > 0) {
|
|
16473
17548
|
const cols = namedCols.map(({ n, i }) => ({ name: n, type: fn.argTypes[i] ?? "text", table: null }));
|
|
@@ -16493,6 +17568,10 @@ function callSqlFunctionScalar(env, fn, args2) {
|
|
|
16493
17568
|
if (fn.language === "plpgsql") {
|
|
16494
17569
|
return callPlpgsqlScalar(env, fn, args2);
|
|
16495
17570
|
}
|
|
17571
|
+
if (fn.language === "internal") {
|
|
17572
|
+
if (fn.rawBody === "pg_trgm") return evalPgTrgmFunction(env.ctx, fn, args2);
|
|
17573
|
+
return evalPgcryptoFunction(env.ctx, fn, args2);
|
|
17574
|
+
}
|
|
16496
17575
|
if (fn.language === "js") {
|
|
16497
17576
|
if (!fn.jsImpl) {
|
|
16498
17577
|
throw pgError("undefined_function", `JavaScript function ${fn.name} is not registered`, "42883");
|
|
@@ -16569,7 +17648,13 @@ function applyWith(env, w) {
|
|
|
16569
17648
|
if (!w) return env;
|
|
16570
17649
|
const ctes = new Map(env.ctes);
|
|
16571
17650
|
for (const cte of w.ctes) {
|
|
16572
|
-
const scopedEnv = {
|
|
17651
|
+
const scopedEnv = {
|
|
17652
|
+
ctx: env.ctx,
|
|
17653
|
+
params: env.params,
|
|
17654
|
+
ctes,
|
|
17655
|
+
outer: env.outer,
|
|
17656
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
17657
|
+
};
|
|
16573
17658
|
let rel2;
|
|
16574
17659
|
if (w.recursive && cte.query.type === "select" && cte.query.body.type === "setop" && cte.query.body.op === "union" && referencesRelation(cte.query.body.right, cte.name)) {
|
|
16575
17660
|
rel2 = executeRecursiveCte(scopedEnv, cte, cte.query);
|
|
@@ -16584,7 +17669,13 @@ function applyWith(env, w) {
|
|
|
16584
17669
|
}
|
|
16585
17670
|
ctes.set(cte.name, applyCteColumnNames(rel2, cte));
|
|
16586
17671
|
}
|
|
16587
|
-
return {
|
|
17672
|
+
return {
|
|
17673
|
+
ctx: env.ctx,
|
|
17674
|
+
params: env.params,
|
|
17675
|
+
ctes,
|
|
17676
|
+
outer: env.outer,
|
|
17677
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
17678
|
+
};
|
|
16588
17679
|
}
|
|
16589
17680
|
var MAX_RECURSION_ITERATIONS = 2e5;
|
|
16590
17681
|
var MAX_RECURSION_ROWS = 5e6;
|
|
@@ -16616,7 +17707,13 @@ function executeRecursiveCte(env, cte, query) {
|
|
|
16616
17707
|
}
|
|
16617
17708
|
const iterCtes = new Map(env.ctes);
|
|
16618
17709
|
iterCtes.set(cte.name, { columns, rows: working });
|
|
16619
|
-
const iterEnv = {
|
|
17710
|
+
const iterEnv = {
|
|
17711
|
+
ctx: env.ctx,
|
|
17712
|
+
params: env.params,
|
|
17713
|
+
ctes: iterCtes,
|
|
17714
|
+
outer: env.outer,
|
|
17715
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
17716
|
+
};
|
|
16620
17717
|
const step = executeBody(iterEnv, body.right);
|
|
16621
17718
|
if (step.columns.length !== columns.length) {
|
|
16622
17719
|
throw pgError("syntax", "each UNION query must have the same number of columns", "42601");
|
|
@@ -16688,7 +17785,7 @@ function materializeItem(env, item, scope) {
|
|
|
16688
17785
|
if (view) {
|
|
16689
17786
|
let rel2;
|
|
16690
17787
|
if (view.materialized) {
|
|
16691
|
-
if (view.
|
|
17788
|
+
if (view.matColumns === null || view.matRows === null && !env.allowUnpopulatedMatviews) {
|
|
16692
17789
|
throw pgError(
|
|
16693
17790
|
"object_not_in_prerequisite_state",
|
|
16694
17791
|
`materialized view "${view.name}" has not been populated`,
|
|
@@ -16697,10 +17794,16 @@ function materializeItem(env, item, scope) {
|
|
|
16697
17794
|
}
|
|
16698
17795
|
rel2 = {
|
|
16699
17796
|
columns: view.matColumns.map((c) => ({ name: c.name, type: c.type, table: label })),
|
|
16700
|
-
rows: view.matRows
|
|
17797
|
+
rows: view.matRows ?? []
|
|
16701
17798
|
};
|
|
16702
17799
|
} else {
|
|
16703
|
-
const viewEnv = {
|
|
17800
|
+
const viewEnv = {
|
|
17801
|
+
ctx: env.ctx,
|
|
17802
|
+
params: null,
|
|
17803
|
+
ctes: /* @__PURE__ */ new Map(),
|
|
17804
|
+
outer: null,
|
|
17805
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
17806
|
+
};
|
|
16704
17807
|
rel2 = executeSelectStmt(viewEnv, view.query);
|
|
16705
17808
|
rel2 = {
|
|
16706
17809
|
columns: rel2.columns.map((c, i) => ({
|
|
@@ -17793,7 +18896,7 @@ function setOpRelation(env, op) {
|
|
|
17793
18896
|
return t === UNKNOWN ? "text" : t;
|
|
17794
18897
|
});
|
|
17795
18898
|
const columns = left.columns.map((c, i) => ({ name: c.name, type: types[i], table: null }));
|
|
17796
|
-
const
|
|
18899
|
+
const normalize2 = (rel2) => rel2.rows.map(
|
|
17797
18900
|
(row) => row.map((v, i) => {
|
|
17798
18901
|
if (v === null) return null;
|
|
17799
18902
|
const srcT = rel2.columns[i].type;
|
|
@@ -17801,8 +18904,8 @@ function setOpRelation(env, op) {
|
|
|
17801
18904
|
return castTo(ctx, tv(srcT === UNKNOWN ? "text" : srcT, v), types[i], {}).v;
|
|
17802
18905
|
})
|
|
17803
18906
|
);
|
|
17804
|
-
const lrows =
|
|
17805
|
-
const rrows =
|
|
18907
|
+
const lrows = normalize2(left);
|
|
18908
|
+
const rrows = normalize2(right);
|
|
17806
18909
|
const keyOf = (row) => row.map((v, i) => v === null ? "\0N" : datumKey(types[i], v)).join("");
|
|
17807
18910
|
let rows;
|
|
17808
18911
|
switch (op.op) {
|
|
@@ -18835,7 +19938,13 @@ function applyUpdateSets(env, table, sets, scope, row) {
|
|
|
18835
19938
|
});
|
|
18836
19939
|
if (typeof set.value === "object" && "kind" in set.value && set.value.kind === "row_subquery") {
|
|
18837
19940
|
const rel2 = executeSelectStmt(
|
|
18838
|
-
{
|
|
19941
|
+
{
|
|
19942
|
+
ctx: env.ctx,
|
|
19943
|
+
params: env.params,
|
|
19944
|
+
ctes: env.ctes,
|
|
19945
|
+
outer: scope,
|
|
19946
|
+
allowUnpopulatedMatviews: env.allowUnpopulatedMatviews
|
|
19947
|
+
},
|
|
18839
19948
|
set.value.query
|
|
18840
19949
|
);
|
|
18841
19950
|
if (rel2.rows.length > 1) {
|
|
@@ -20618,6 +21727,9 @@ function executeTrigger(env, table, trigger, _event, oldRow, newRow) {
|
|
|
20618
21727
|
setTriggerExecutor(executeTrigger);
|
|
20619
21728
|
|
|
20620
21729
|
// src/executor/ddl.ts
|
|
21730
|
+
function matviewQueryEnv(env, allowUnpopulatedMatviews) {
|
|
21731
|
+
return { ctx: env.ctx, params: null, ctes: /* @__PURE__ */ new Map(), outer: null, allowUnpopulatedMatviews };
|
|
21732
|
+
}
|
|
20621
21733
|
function targetSchema(env, parts) {
|
|
20622
21734
|
const state = env.ctx.state;
|
|
20623
21735
|
if (parts.length >= 2) {
|
|
@@ -21021,6 +22133,7 @@ function executeCreateIndex(env, stmt) {
|
|
|
21021
22133
|
}
|
|
21022
22134
|
}
|
|
21023
22135
|
}
|
|
22136
|
+
assertGinTrgmIndex(state, table, stmt);
|
|
21024
22137
|
schema.indexes.set(name, {
|
|
21025
22138
|
name,
|
|
21026
22139
|
schema: schema.name,
|
|
@@ -21065,7 +22178,7 @@ function executeCreateView(env, stmt) {
|
|
|
21065
22178
|
let matRows = null;
|
|
21066
22179
|
let matColumns = null;
|
|
21067
22180
|
if (stmt.materialized) {
|
|
21068
|
-
const rel2 = executeSelectStmt(
|
|
22181
|
+
const rel2 = executeSelectStmt(matviewQueryEnv(env, !stmt.withData), stmt.query);
|
|
21069
22182
|
matColumns = rel2.columns.map((c, i) => ({
|
|
21070
22183
|
name: stmt.columns?.[i] ?? c.name,
|
|
21071
22184
|
type: c.type === UNKNOWN ? "text" : c.type
|
|
@@ -21091,7 +22204,7 @@ function executeRefreshMatView(env, stmt) {
|
|
|
21091
22204
|
throw pgError("undefined_table", `materialized view "${stmt.name.join(".")}" does not exist`, "42P01");
|
|
21092
22205
|
}
|
|
21093
22206
|
const view = env.ctx.state.ensureWritableView(found);
|
|
21094
|
-
const rel2 = executeSelectStmt(
|
|
22207
|
+
const rel2 = executeSelectStmt(matviewQueryEnv(env, !stmt.withData), view.query);
|
|
21095
22208
|
view.matColumns = rel2.columns.map((c, i) => ({
|
|
21096
22209
|
name: view.columns?.[i] ?? c.name,
|
|
21097
22210
|
type: c.type === UNKNOWN ? "text" : c.type
|
|
@@ -21099,6 +22212,32 @@ function executeRefreshMatView(env, stmt) {
|
|
|
21099
22212
|
view.matRows = stmt.withData ? rel2.rows : null;
|
|
21100
22213
|
return commandResult("REFRESH MATERIALIZED VIEW", 0);
|
|
21101
22214
|
}
|
|
22215
|
+
function executeCreateExtension(env, stmt) {
|
|
22216
|
+
const state = env.ctx.state;
|
|
22217
|
+
const schemaName = stmt.schema ?? state.currentSchema();
|
|
22218
|
+
const install = () => {
|
|
22219
|
+
if (stmt.name === "pgcrypto") {
|
|
22220
|
+
if (pgcryptoInstalled(state)) return "exists";
|
|
22221
|
+
installPgcrypto(state, state.getSchema(schemaName).name);
|
|
22222
|
+
return "installed";
|
|
22223
|
+
}
|
|
22224
|
+
if (stmt.name === "pg_trgm") {
|
|
22225
|
+
if (pgTrgmInstalled(state)) return "exists";
|
|
22226
|
+
installPgTrgm(state, state.getSchema(schemaName).name);
|
|
22227
|
+
return "installed";
|
|
22228
|
+
}
|
|
22229
|
+
return "unsupported";
|
|
22230
|
+
};
|
|
22231
|
+
const outcome = install();
|
|
22232
|
+
if (outcome === "unsupported") {
|
|
22233
|
+
throw pgError("feature_not_supported", `extension "${stmt.name}" is not available`, "0A000");
|
|
22234
|
+
}
|
|
22235
|
+
if (outcome === "exists") {
|
|
22236
|
+
if (stmt.ifNotExists) return commandResult("CREATE EXTENSION", 0);
|
|
22237
|
+
throw pgError("duplicate_object", `extension "${stmt.name}" already exists`, "42710");
|
|
22238
|
+
}
|
|
22239
|
+
return commandResult("CREATE EXTENSION", 0);
|
|
22240
|
+
}
|
|
21102
22241
|
function executeCreateSchema(env, stmt) {
|
|
21103
22242
|
const state = env.ctx.state;
|
|
21104
22243
|
if (state.schemas.has(stmt.name)) {
|
|
@@ -21887,8 +23026,19 @@ function executeDrop(env, stmt) {
|
|
|
21887
23026
|
table.triggers.splice(idx, 1);
|
|
21888
23027
|
break;
|
|
21889
23028
|
}
|
|
21890
|
-
case "extension":
|
|
21891
|
-
|
|
23029
|
+
case "extension": {
|
|
23030
|
+
const ext = parts[parts.length - 1];
|
|
23031
|
+
if (ext === "pgcrypto" && pgcryptoInstalled(state)) {
|
|
23032
|
+
uninstallPgcrypto(state);
|
|
23033
|
+
break;
|
|
23034
|
+
}
|
|
23035
|
+
if (ext === "pg_trgm" && pgTrgmInstalled(state)) {
|
|
23036
|
+
uninstallPgTrgm(state);
|
|
23037
|
+
break;
|
|
23038
|
+
}
|
|
23039
|
+
if (stmt.ifExists) break;
|
|
23040
|
+
throw pgError("undefined_object", `extension "${ext}" does not exist`, "42704");
|
|
23041
|
+
}
|
|
21892
23042
|
}
|
|
21893
23043
|
}
|
|
21894
23044
|
const label = stmt.kind === "materialized_view" ? "MATERIALIZED VIEW" : stmt.kind.toUpperCase();
|
|
@@ -21970,6 +23120,8 @@ function executeStatement(env, stmt) {
|
|
|
21970
23120
|
return executeAlterSequence(env, stmt);
|
|
21971
23121
|
case "create_schema":
|
|
21972
23122
|
return executeCreateSchema(env, stmt);
|
|
23123
|
+
case "create_extension":
|
|
23124
|
+
return executeCreateExtension(env, stmt);
|
|
21973
23125
|
case "create_enum":
|
|
21974
23126
|
return executeCreateEnum(env, stmt);
|
|
21975
23127
|
case "alter_enum":
|
|
@@ -22125,6 +23277,9 @@ var ADOPT = /* @__PURE__ */ Symbol("postgres-mem.adopt");
|
|
|
22125
23277
|
function isAdopted(value) {
|
|
22126
23278
|
return ADOPT in value;
|
|
22127
23279
|
}
|
|
23280
|
+
function project(point) {
|
|
23281
|
+
return { id: point.id, branch: point.branch, parent: point.parent, at: point.at };
|
|
23282
|
+
}
|
|
22128
23283
|
var Database = class {
|
|
22129
23284
|
/** @internal Engine catalog, tables, session settings. */
|
|
22130
23285
|
state;
|
|
@@ -22145,6 +23300,10 @@ var Database = class {
|
|
|
22145
23300
|
closed = false;
|
|
22146
23301
|
transactionSequence = 0;
|
|
22147
23302
|
apiTransactionDepth = 0;
|
|
23303
|
+
/** @internal Shared checkpoint DAG. Omitted from published declarations. */
|
|
23304
|
+
timeline;
|
|
23305
|
+
historyBranch = "main";
|
|
23306
|
+
originId = "";
|
|
22148
23307
|
constructor(options2 = {}) {
|
|
22149
23308
|
if (isAdopted(options2)) {
|
|
22150
23309
|
this.seed = options2.seed;
|
|
@@ -22157,16 +23316,23 @@ var Database = class {
|
|
|
22157
23316
|
this.state.prng = this.prng;
|
|
22158
23317
|
this.state.clock = () => this.now();
|
|
22159
23318
|
this.transactions = txManagerFor(this.state);
|
|
22160
|
-
|
|
23319
|
+
} else {
|
|
23320
|
+
this.seed = options2.seed ?? DEFAULT_DATABASE_SEED;
|
|
23321
|
+
this.randomMode = options2.random ?? "deterministic";
|
|
23322
|
+
this.systemClock = options2.now === "system";
|
|
23323
|
+
this.int8Mode = options2.int8 ?? "bigint";
|
|
23324
|
+
this.prng = this.randomMode === "os" ? new OsEntropy() : new Prng(this.seed);
|
|
23325
|
+
this.now = resolveClock(options2.now);
|
|
23326
|
+
this.state = new DatabaseState(this.prng, () => this.now());
|
|
23327
|
+
this.transactions = txManagerFor(this.state);
|
|
22161
23328
|
}
|
|
22162
|
-
this.
|
|
22163
|
-
|
|
22164
|
-
|
|
22165
|
-
|
|
22166
|
-
|
|
22167
|
-
this.
|
|
22168
|
-
this.
|
|
22169
|
-
this.transactions = txManagerFor(this.state);
|
|
23329
|
+
this.timeline = new Timeline({
|
|
23330
|
+
now: () => this.now().getTime(),
|
|
23331
|
+
...options2.maxCheckpoints !== void 0 ? { maxCheckpoints: options2.maxCheckpoints } : {}
|
|
23332
|
+
});
|
|
23333
|
+
const origin = this.timeline.commit(this.captureLive());
|
|
23334
|
+
this.originId = origin.id;
|
|
23335
|
+
this.timeline.retain(origin.id);
|
|
22170
23336
|
}
|
|
22171
23337
|
/**
|
|
22172
23338
|
* Execute SQL for its side effects. Multiple semicolon-separated statements
|
|
@@ -22221,7 +23387,15 @@ var Database = class {
|
|
|
22221
23387
|
/** Execute a single-statement query and return all rows keyed by column name. */
|
|
22222
23388
|
query(sql, params = [], options2 = {}) {
|
|
22223
23389
|
this.assertOpen();
|
|
22224
|
-
|
|
23390
|
+
const at = options2.at;
|
|
23391
|
+
if (typeof at === "string") {
|
|
23392
|
+
try {
|
|
23393
|
+
return this.timeline.get(at).value.open().query(sql, params);
|
|
23394
|
+
} catch (error) {
|
|
23395
|
+
this.historyError(error);
|
|
23396
|
+
}
|
|
23397
|
+
}
|
|
23398
|
+
if (at) return at.open().query(sql, params);
|
|
22225
23399
|
return this.prepareSingle(sql).all(...params);
|
|
22226
23400
|
}
|
|
22227
23401
|
/** Compile a single SQL statement into a reusable {@link Statement}. */
|
|
@@ -22269,23 +23443,77 @@ var Database = class {
|
|
|
22269
23443
|
* {@link Snapshot.open} for a copy-on-write fork.
|
|
22270
23444
|
*/
|
|
22271
23445
|
snapshot() {
|
|
23446
|
+
const point = this.record(this.historyBranch);
|
|
23447
|
+
return this.timeline.get(point.id).value;
|
|
23448
|
+
}
|
|
23449
|
+
/** Alias for {@link snapshot}, naming the value as a timeline checkpoint. */
|
|
23450
|
+
checkpoint() {
|
|
23451
|
+
return this.snapshot();
|
|
23452
|
+
}
|
|
23453
|
+
/**
|
|
23454
|
+
* Commit the live state onto `branch` (default: the branch this database follows).
|
|
23455
|
+
* Does not switch the live database. Illegal inside a transaction.
|
|
23456
|
+
*/
|
|
23457
|
+
record(branch = this.historyBranch) {
|
|
22272
23458
|
this.assertOpen();
|
|
22273
23459
|
if (this.transactions.inTransaction) {
|
|
22274
23460
|
throw pgError("transaction_state", "cannot snapshot during a transaction", "25P01");
|
|
22275
23461
|
}
|
|
22276
|
-
|
|
22277
|
-
this.
|
|
22278
|
-
|
|
22279
|
-
this.
|
|
22280
|
-
|
|
22281
|
-
this.randomMode,
|
|
22282
|
-
this.systemClock,
|
|
22283
|
-
this.int8Mode
|
|
22284
|
-
);
|
|
23462
|
+
try {
|
|
23463
|
+
return project(this.timeline.commit(this.captureLive(), { branch }));
|
|
23464
|
+
} catch (error) {
|
|
23465
|
+
this.historyError(error);
|
|
23466
|
+
}
|
|
22285
23467
|
}
|
|
22286
|
-
/**
|
|
22287
|
-
|
|
22288
|
-
|
|
23468
|
+
/** Point `name` at a checkpoint without copying rows or switching the live database. */
|
|
23469
|
+
fork(name, at) {
|
|
23470
|
+
this.assertOpen();
|
|
23471
|
+
try {
|
|
23472
|
+
const point = this.timeline.fork(name, at !== void 0 ? { from: at } : {});
|
|
23473
|
+
if (!point) throw pgError("misuse", "no checkpoint to fork from", "XX000");
|
|
23474
|
+
return project(point);
|
|
23475
|
+
} catch (error) {
|
|
23476
|
+
if (error instanceof PostgresError) throw error;
|
|
23477
|
+
this.historyError(error);
|
|
23478
|
+
}
|
|
23479
|
+
}
|
|
23480
|
+
/** Move `branch` to `id` and install that checkpoint as the live database. */
|
|
23481
|
+
checkout(id, branch = this.historyBranch) {
|
|
23482
|
+
this.assertOpen();
|
|
23483
|
+
if (this.transactions.inTransaction) {
|
|
23484
|
+
throw pgError("transaction_state", "cannot checkout during a transaction", "25P01");
|
|
23485
|
+
}
|
|
23486
|
+
try {
|
|
23487
|
+
const point = this.timeline.checkout(branch, id);
|
|
23488
|
+
this.historyBranch = branch;
|
|
23489
|
+
this.install(point.value);
|
|
23490
|
+
return project(point);
|
|
23491
|
+
} catch (error) {
|
|
23492
|
+
this.historyError(error);
|
|
23493
|
+
}
|
|
23494
|
+
}
|
|
23495
|
+
/** Return the live database to the origin checkpoint on `main`. */
|
|
23496
|
+
reset() {
|
|
23497
|
+
return this.checkout(this.originId, "main");
|
|
23498
|
+
}
|
|
23499
|
+
/** Checkpoint ids and branch heads. Values stay inside the timeline. */
|
|
23500
|
+
get history() {
|
|
23501
|
+
const timeline = this.timeline;
|
|
23502
|
+
return {
|
|
23503
|
+
get size() {
|
|
23504
|
+
return timeline.size;
|
|
23505
|
+
},
|
|
23506
|
+
head(branch) {
|
|
23507
|
+
const point = timeline.head(branch);
|
|
23508
|
+
return point ? project(point) : void 0;
|
|
23509
|
+
},
|
|
23510
|
+
branches() {
|
|
23511
|
+
return timeline.branches();
|
|
23512
|
+
},
|
|
23513
|
+
checkpoints() {
|
|
23514
|
+
return timeline.checkpoints().map(project);
|
|
23515
|
+
}
|
|
23516
|
+
};
|
|
22289
23517
|
}
|
|
22290
23518
|
/** Open a copy-on-write branch from `at`, or from the current state when omitted. */
|
|
22291
23519
|
branch(at = this.snapshot()) {
|
|
@@ -22330,6 +23558,26 @@ var Database = class {
|
|
|
22330
23558
|
assertOpen() {
|
|
22331
23559
|
if (this.closed) throw pgError("misuse", "Database is closed", "XX000");
|
|
22332
23560
|
}
|
|
23561
|
+
historyError(error) {
|
|
23562
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
23563
|
+
throw pgError("misuse", message2, "XX000");
|
|
23564
|
+
}
|
|
23565
|
+
captureLive() {
|
|
23566
|
+
return captureSnapshot(
|
|
23567
|
+
this.state,
|
|
23568
|
+
this.prng,
|
|
23569
|
+
this.now,
|
|
23570
|
+
this.seed,
|
|
23571
|
+
this.randomMode,
|
|
23572
|
+
this.systemClock,
|
|
23573
|
+
this.int8Mode
|
|
23574
|
+
);
|
|
23575
|
+
}
|
|
23576
|
+
install(snapshot) {
|
|
23577
|
+
this.state.restoreFrom(snapshot.state.cloneShallow());
|
|
23578
|
+
this.prng.setState(snapshot.prngState);
|
|
23579
|
+
if (!this.systemClock) this.now = fixedClock(new Date(snapshot.nowMs));
|
|
23580
|
+
}
|
|
22333
23581
|
prepareSingle(sql) {
|
|
22334
23582
|
const statements = parse(sql);
|
|
22335
23583
|
if (statements.length === 0) {
|
|
@@ -22789,7 +24037,7 @@ var FrameParser = class {
|
|
|
22789
24037
|
return { kind: "typed", type, body };
|
|
22790
24038
|
}
|
|
22791
24039
|
};
|
|
22792
|
-
var
|
|
24040
|
+
var utf83 = {
|
|
22793
24041
|
encode: (s) => encoder2.encode(s),
|
|
22794
24042
|
decode: (b) => decoder.decode(b)
|
|
22795
24043
|
};
|
|
@@ -23010,13 +24258,13 @@ var binaryValue = (type, text) => {
|
|
|
23010
24258
|
return out;
|
|
23011
24259
|
}
|
|
23012
24260
|
default:
|
|
23013
|
-
return TEXT_TYPES2.has(type) ?
|
|
24261
|
+
return TEXT_TYPES2.has(type) ? utf83.encode(text) : null;
|
|
23014
24262
|
}
|
|
23015
24263
|
};
|
|
23016
24264
|
var binaryEncodable = (type) => TEXT_TYPES2.has(type) || ["bool", "int2", "int4", "oid", "int8", "float4", "float8", "bytea", "uuid"].includes(type);
|
|
23017
24265
|
var decodeParam = (oid, format, bytes) => {
|
|
23018
24266
|
if (bytes === null) return null;
|
|
23019
|
-
if (format === 0) return
|
|
24267
|
+
if (format === 0) return utf83.decode(bytes);
|
|
23020
24268
|
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
23021
24269
|
switch (oid) {
|
|
23022
24270
|
case 16:
|
|
@@ -23052,7 +24300,7 @@ var decodeParam = (oid, format, bytes) => {
|
|
|
23052
24300
|
case 1042:
|
|
23053
24301
|
case 1043:
|
|
23054
24302
|
case 3802:
|
|
23055
|
-
return
|
|
24303
|
+
return utf83.decode(bytes);
|
|
23056
24304
|
default:
|
|
23057
24305
|
throw pgError2("internal", `binary parameter format is not supported for type oid ${oid}`, "0A000");
|
|
23058
24306
|
}
|
|
@@ -23219,6 +24467,11 @@ var Connection = class {
|
|
|
23219
24467
|
return;
|
|
23220
24468
|
}
|
|
23221
24469
|
this.user = parameters.user ?? "postgres";
|
|
24470
|
+
const requested = parameters.database && parameters.database.length > 0 ? parameters.database : this.user;
|
|
24471
|
+
if (this.options.database !== void 0 && requested !== this.options.database) {
|
|
24472
|
+
this.fatal("3D000", `database "${requested}" does not exist`);
|
|
24473
|
+
return;
|
|
24474
|
+
}
|
|
23222
24475
|
if (this.options.password !== void 0) {
|
|
23223
24476
|
this.scram = new ScramServer(this.options.password);
|
|
23224
24477
|
this.write(backend.authenticationSASL(["SCRAM-SHA-256"]));
|
|
@@ -23234,7 +24487,7 @@ var Connection = class {
|
|
|
23234
24487
|
if (!this.scramStarted) {
|
|
23235
24488
|
const mechanism = body.cstring();
|
|
23236
24489
|
const length = body.i32();
|
|
23237
|
-
const clientFirst =
|
|
24490
|
+
const clientFirst = utf83.decode(body.take(length));
|
|
23238
24491
|
const serverFirst = mechanism === "SCRAM-SHA-256" ? this.scram.first(clientFirst) : null;
|
|
23239
24492
|
if (serverFirst === null) {
|
|
23240
24493
|
this.fatal("28000", `SASL authentication with ${mechanism} is not supported or malformed`);
|
|
@@ -23244,7 +24497,7 @@ var Connection = class {
|
|
|
23244
24497
|
this.write(backend.authenticationSASLContinue(serverFirst));
|
|
23245
24498
|
return;
|
|
23246
24499
|
}
|
|
23247
|
-
const serverFinal = this.scram.final(
|
|
24500
|
+
const serverFinal = this.scram.final(utf83.decode(body.rest()));
|
|
23248
24501
|
if (serverFinal === null) {
|
|
23249
24502
|
this.fatal("28P01", `password authentication failed for user "${this.user}"`);
|
|
23250
24503
|
return;
|
|
@@ -23492,7 +24745,7 @@ var Connection = class {
|
|
|
23492
24745
|
row.map((value, c) => {
|
|
23493
24746
|
if (value === null) return null;
|
|
23494
24747
|
const type = result.columnTypes[c];
|
|
23495
|
-
return formats[c] === 1 ? binaryValue(type, value) ??
|
|
24748
|
+
return formats[c] === 1 ? binaryValue(type, value) ?? utf83.encode(value) : utf83.encode(value);
|
|
23496
24749
|
})
|
|
23497
24750
|
)
|
|
23498
24751
|
);
|
|
@@ -23660,13 +24913,53 @@ var ConnectionDropped = class extends Error {
|
|
|
23660
24913
|
};
|
|
23661
24914
|
|
|
23662
24915
|
// src/wire/index.ts
|
|
24916
|
+
var parseUri = (raw) => {
|
|
24917
|
+
let url;
|
|
24918
|
+
try {
|
|
24919
|
+
url = new URL(raw);
|
|
24920
|
+
} catch {
|
|
24921
|
+
throw new Error(`invalid postgres URI: ${raw}`);
|
|
24922
|
+
}
|
|
24923
|
+
if (url.protocol !== "postgres:" && url.protocol !== "postgresql:") {
|
|
24924
|
+
throw new Error(`unsupported postgres URI protocol ${url.protocol}`);
|
|
24925
|
+
}
|
|
24926
|
+
const databaseName = decodeURIComponent(url.pathname.replace(/^\//, ""));
|
|
24927
|
+
const password = url.password === "" ? void 0 : decodeURIComponent(url.password);
|
|
24928
|
+
const user = decodeURIComponent(url.username || "postgres");
|
|
24929
|
+
const port = url.port === "" ? 5432 : Number(url.port);
|
|
24930
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) throw new Error(`invalid postgres URI port: ${url.port}`);
|
|
24931
|
+
return {
|
|
24932
|
+
host: url.hostname || "127.0.0.1",
|
|
24933
|
+
port,
|
|
24934
|
+
user,
|
|
24935
|
+
...password !== void 0 ? { password } : {},
|
|
24936
|
+
...databaseName !== "" ? { databaseName } : {}
|
|
24937
|
+
};
|
|
24938
|
+
};
|
|
24939
|
+
var normalize = (input) => {
|
|
24940
|
+
if (typeof input === "string") return parseUri(input);
|
|
24941
|
+
if (input.url === void 0) return input;
|
|
24942
|
+
const parsed = parseUri(input.url);
|
|
24943
|
+
return {
|
|
24944
|
+
...parsed,
|
|
24945
|
+
...input,
|
|
24946
|
+
host: input.host ?? parsed.host,
|
|
24947
|
+
port: input.port ?? parsed.port,
|
|
24948
|
+
password: input.password ?? parsed.password,
|
|
24949
|
+
databaseName: input.databaseName ?? parsed.databaseName,
|
|
24950
|
+
user: input.user ?? parsed.user,
|
|
24951
|
+
parameters: input.parameters ?? parsed.parameters
|
|
24952
|
+
};
|
|
24953
|
+
};
|
|
23663
24954
|
var isSnapshot = (value) => typeof value === "object" && value !== null && "open" in value && typeof value.open === "function";
|
|
23664
|
-
var serve = (
|
|
24955
|
+
var serve = (input = {}) => {
|
|
24956
|
+
const options2 = normalize(input);
|
|
23665
24957
|
const database = isSnapshot(options2.database) ? options2.database.open() : options2.database ?? new Database();
|
|
23666
24958
|
const cluster = new Cluster(database);
|
|
23667
24959
|
const faults = {};
|
|
23668
24960
|
const connections = /* @__PURE__ */ new Set();
|
|
23669
24961
|
const host = options2.host ?? "127.0.0.1";
|
|
24962
|
+
const user = options2.user || "postgres";
|
|
23670
24963
|
const server2 = createServer((socket) => {
|
|
23671
24964
|
socket.setNoDelay(true);
|
|
23672
24965
|
const connection = new Connection(socket, cluster, {
|
|
@@ -23674,6 +24967,7 @@ var serve = (options2 = {}) => {
|
|
|
23674
24967
|
serverVersion: options2.serverVersion ?? "18.3",
|
|
23675
24968
|
parameters: options2.parameters ?? {},
|
|
23676
24969
|
faults,
|
|
24970
|
+
...options2.databaseName !== void 0 ? { database: options2.databaseName } : {},
|
|
23677
24971
|
...options2.onLog ? { onLog: options2.onLog } : {}
|
|
23678
24972
|
});
|
|
23679
24973
|
connections.add(connection);
|
|
@@ -23685,9 +24979,12 @@ var serve = (options2 = {}) => {
|
|
|
23685
24979
|
server2.removeListener("error", reject);
|
|
23686
24980
|
const address = server2.address();
|
|
23687
24981
|
const port = typeof address === "object" && address !== null ? address.port : 0;
|
|
24982
|
+
const name = options2.databaseName ?? "postgres";
|
|
24983
|
+
const auth = options2.password ? `${encodeURIComponent(user)}:${encodeURIComponent(options2.password)}@` : `${encodeURIComponent(user)}@`;
|
|
23688
24984
|
resolve({
|
|
23689
24985
|
port,
|
|
23690
24986
|
host,
|
|
24987
|
+
connectionString: `postgres://${auth}${host}:${port}/${encodeURIComponent(name)}`,
|
|
23691
24988
|
database,
|
|
23692
24989
|
server: server2,
|
|
23693
24990
|
get connections() {
|
|
@@ -23712,7 +25009,7 @@ var serve = (options2 = {}) => {
|
|
|
23712
25009
|
};
|
|
23713
25010
|
|
|
23714
25011
|
// src/wire/cli.ts
|
|
23715
|
-
var usage = `mockingbird-postgres serve [--port <n>] [--host <h>] [--password <p>] [--server-version <v>] [--log]`;
|
|
25012
|
+
var usage = `mockingbird-postgres serve [postgres://URI] [--port <n>] [--host <h>] [--password <p>] [--server-version <v>] [--log]`;
|
|
23716
25013
|
var args = process.argv.slice(2);
|
|
23717
25014
|
if (args[0] !== "serve") {
|
|
23718
25015
|
console.error(usage);
|
|
@@ -23722,6 +25019,10 @@ var options = {};
|
|
|
23722
25019
|
var log = false;
|
|
23723
25020
|
for (let i = 1; i < args.length; i++) {
|
|
23724
25021
|
const flag = args[i];
|
|
25022
|
+
if (flag !== void 0 && (flag.startsWith("postgres://") || flag.startsWith("postgresql://"))) {
|
|
25023
|
+
options.url = flag;
|
|
25024
|
+
continue;
|
|
25025
|
+
}
|
|
23725
25026
|
const value = args[i + 1];
|
|
23726
25027
|
const need = () => {
|
|
23727
25028
|
if (value === void 0) {
|
|
@@ -23759,8 +25060,7 @@ if (log) {
|
|
|
23759
25060
|
);
|
|
23760
25061
|
}
|
|
23761
25062
|
var server = await serve(options);
|
|
23762
|
-
|
|
23763
|
-
console.log(`mockingbird-postgres listening on postgres://${auth}${server.host}:${server.port}/postgres`);
|
|
25063
|
+
console.log(`mockingbird-postgres listening on ${server.connectionString}`);
|
|
23764
25064
|
var stop = async () => {
|
|
23765
25065
|
await server.close();
|
|
23766
25066
|
process.exit(0);
|