@crvouga/postgres-mem 0.1.0 → 1.0.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/dist/index.js +1726 -116
- package/dist/index.js.map +4 -4
- package/dist/unstable.js +1242 -112
- package/dist/unstable.js.map +4 -4
- package/package.json +8 -4
- package/compat/gate-report.json +0 -80
- package/compat/requirements.raw.html +0 -484
package/dist/index.js
CHANGED
|
@@ -190,6 +190,9 @@ var OsEntropy = class _OsEntropy extends Prng {
|
|
|
190
190
|
|
|
191
191
|
// src/schema/catalog.ts
|
|
192
192
|
var builder = null;
|
|
193
|
+
function setCatalogBuilder(b) {
|
|
194
|
+
builder = b;
|
|
195
|
+
}
|
|
193
196
|
function catalogRelation(ctx, schema, name) {
|
|
194
197
|
if (schema !== "pg_catalog" && schema !== "information_schema") return null;
|
|
195
198
|
return builder ? builder(ctx, schema, name) : null;
|
|
@@ -2490,6 +2493,36 @@ var TYPE_OIDS = {
|
|
|
2490
2493
|
void: 2278,
|
|
2491
2494
|
unknown: 705
|
|
2492
2495
|
};
|
|
2496
|
+
var ARRAY_OIDS = {
|
|
2497
|
+
bool: 1e3,
|
|
2498
|
+
bytea: 1001,
|
|
2499
|
+
name: 1003,
|
|
2500
|
+
int8: 1016,
|
|
2501
|
+
int2: 1005,
|
|
2502
|
+
int4: 1007,
|
|
2503
|
+
text: 1009,
|
|
2504
|
+
oid: 1028,
|
|
2505
|
+
json: 199,
|
|
2506
|
+
float4: 1021,
|
|
2507
|
+
float8: 1022,
|
|
2508
|
+
money: 791,
|
|
2509
|
+
bpchar: 1014,
|
|
2510
|
+
varchar: 1015,
|
|
2511
|
+
date: 1182,
|
|
2512
|
+
time: 1183,
|
|
2513
|
+
timestamp: 1115,
|
|
2514
|
+
timestamptz: 1185,
|
|
2515
|
+
interval: 1187,
|
|
2516
|
+
timetz: 1270,
|
|
2517
|
+
numeric: 1231,
|
|
2518
|
+
record: 2287,
|
|
2519
|
+
uuid: 2951,
|
|
2520
|
+
jsonb: 3807
|
|
2521
|
+
};
|
|
2522
|
+
function typeOid(t) {
|
|
2523
|
+
if (isArrayType(t)) return ARRAY_OIDS[arrayElemType(t)] ?? 2277;
|
|
2524
|
+
return TYPE_OIDS[t] ?? 705;
|
|
2525
|
+
}
|
|
2493
2526
|
function shortestParts(v) {
|
|
2494
2527
|
const s = Math.abs(v).toString();
|
|
2495
2528
|
if (s.includes("e") || s.includes("E")) {
|
|
@@ -3906,13 +3939,13 @@ var RowScope = class {
|
|
|
3906
3939
|
function childEnv(env, outer) {
|
|
3907
3940
|
return { ctx: env.ctx, params: env.params, ctes: env.ctes, outer };
|
|
3908
3941
|
}
|
|
3909
|
-
function relationResult(
|
|
3910
|
-
const visible =
|
|
3942
|
+
function relationResult(rel2, command) {
|
|
3943
|
+
const visible = rel2.columns.map((c, i) => ({ i, c })).filter(({ c }) => !c.hidden);
|
|
3911
3944
|
return {
|
|
3912
3945
|
columns: visible.map(({ c }) => ({ name: c.name, type: c.type })),
|
|
3913
|
-
rows:
|
|
3946
|
+
rows: rel2.rows.map((r) => visible.map(({ i }) => r[i] ?? null)),
|
|
3914
3947
|
command,
|
|
3915
|
-
rowCount:
|
|
3948
|
+
rowCount: rel2.rows.length
|
|
3916
3949
|
};
|
|
3917
3950
|
}
|
|
3918
3951
|
function commandResult(command, rowCount) {
|
|
@@ -10391,6 +10424,9 @@ var FACTORIES = /* @__PURE__ */ new Map([
|
|
|
10391
10424
|
["regr_syy", () => new CorrAcc("regr_syy")],
|
|
10392
10425
|
["regr_sxy", () => new CorrAcc("regr_sxy")]
|
|
10393
10426
|
]);
|
|
10427
|
+
function getAggregateFactories() {
|
|
10428
|
+
return FACTORIES;
|
|
10429
|
+
}
|
|
10394
10430
|
function isAggregateName(name) {
|
|
10395
10431
|
return FACTORIES.has(name);
|
|
10396
10432
|
}
|
|
@@ -11109,31 +11145,31 @@ function makeEvalScope(env, scope, extras) {
|
|
|
11109
11145
|
return p;
|
|
11110
11146
|
},
|
|
11111
11147
|
execScalarSubquery(q) {
|
|
11112
|
-
const
|
|
11113
|
-
if (
|
|
11148
|
+
const rel2 = executeSelectStmt(childEnv(env, scope), q);
|
|
11149
|
+
if (rel2.columns.length !== 1) {
|
|
11114
11150
|
throw pgError("cardinality_violation", "subquery must return only one column", "42601");
|
|
11115
11151
|
}
|
|
11116
|
-
if (
|
|
11152
|
+
if (rel2.rows.length > 1) {
|
|
11117
11153
|
throw pgError(
|
|
11118
11154
|
"cardinality_violation",
|
|
11119
11155
|
"more than one row returned by a subquery used as an expression",
|
|
11120
11156
|
"21000"
|
|
11121
11157
|
);
|
|
11122
11158
|
}
|
|
11123
|
-
const t =
|
|
11124
|
-
return tv(t === UNKNOWN ? "text" : t,
|
|
11159
|
+
const t = rel2.columns[0].type;
|
|
11160
|
+
return tv(t === UNKNOWN ? "text" : t, rel2.rows[0]?.[0] ?? null);
|
|
11125
11161
|
},
|
|
11126
11162
|
execExistsSubquery(q) {
|
|
11127
|
-
const
|
|
11128
|
-
return
|
|
11163
|
+
const rel2 = executeSelectStmt(childEnv(env, scope), q);
|
|
11164
|
+
return rel2.rows.length > 0;
|
|
11129
11165
|
},
|
|
11130
11166
|
execColumnSubquery(q) {
|
|
11131
|
-
const
|
|
11132
|
-
if (
|
|
11167
|
+
const rel2 = executeSelectStmt(childEnv(env, scope), q);
|
|
11168
|
+
if (rel2.columns.length !== 1) {
|
|
11133
11169
|
throw pgError("cardinality_violation", "subquery has too many columns", "42601");
|
|
11134
11170
|
}
|
|
11135
|
-
const t =
|
|
11136
|
-
return { type: t === UNKNOWN ? "text" : t, values:
|
|
11171
|
+
const t = rel2.columns[0].type;
|
|
11172
|
+
return { type: t === UNKNOWN ? "text" : t, values: rel2.rows.map((r) => r[0] ?? null) };
|
|
11137
11173
|
},
|
|
11138
11174
|
aggValue(node) {
|
|
11139
11175
|
return extras?.aggMap?.get(node);
|
|
@@ -11249,39 +11285,39 @@ function referencesRelation(node, name) {
|
|
|
11249
11285
|
}
|
|
11250
11286
|
return false;
|
|
11251
11287
|
}
|
|
11252
|
-
function applyCteColumnNames(
|
|
11253
|
-
const columns =
|
|
11288
|
+
function applyCteColumnNames(rel2, cte) {
|
|
11289
|
+
const columns = rel2.columns.map((c, i) => ({
|
|
11254
11290
|
name: cte.columns?.[i] ?? c.name,
|
|
11255
11291
|
type: c.type,
|
|
11256
11292
|
table: null
|
|
11257
11293
|
}));
|
|
11258
|
-
if (cte.columns && cte.columns.length >
|
|
11294
|
+
if (cte.columns && cte.columns.length > rel2.columns.length) {
|
|
11259
11295
|
throw pgError(
|
|
11260
11296
|
"syntax",
|
|
11261
|
-
`WITH query "${cte.name}" has ${
|
|
11297
|
+
`WITH query "${cte.name}" has ${rel2.columns.length} columns available but ${cte.columns.length} columns specified`,
|
|
11262
11298
|
"42P10"
|
|
11263
11299
|
);
|
|
11264
11300
|
}
|
|
11265
|
-
return { columns, rows:
|
|
11301
|
+
return { columns, rows: rel2.rows };
|
|
11266
11302
|
}
|
|
11267
11303
|
function applyWith(env, w) {
|
|
11268
11304
|
if (!w) return env;
|
|
11269
11305
|
const ctes = new Map(env.ctes);
|
|
11270
11306
|
for (const cte of w.ctes) {
|
|
11271
11307
|
const scopedEnv = { ctx: env.ctx, params: env.params, ctes, outer: env.outer };
|
|
11272
|
-
let
|
|
11308
|
+
let rel2;
|
|
11273
11309
|
if (w.recursive && cte.query.type === "select" && cte.query.body.type === "setop" && cte.query.body.op === "union" && referencesRelation(cte.query.body.right, cte.name)) {
|
|
11274
|
-
|
|
11310
|
+
rel2 = executeRecursiveCte(scopedEnv, cte, cte.query);
|
|
11275
11311
|
} else if (cte.query.type === "select") {
|
|
11276
|
-
|
|
11312
|
+
rel2 = executeSelectStmt(scopedEnv, cte.query);
|
|
11277
11313
|
} else {
|
|
11278
11314
|
const res = runStatement(scopedEnv, cte.query);
|
|
11279
|
-
|
|
11315
|
+
rel2 = {
|
|
11280
11316
|
columns: res.columns.map((c) => ({ name: c.name, type: c.type, table: null })),
|
|
11281
11317
|
rows: res.rows
|
|
11282
11318
|
};
|
|
11283
11319
|
}
|
|
11284
|
-
ctes.set(cte.name, applyCteColumnNames(
|
|
11320
|
+
ctes.set(cte.name, applyCteColumnNames(rel2, cte));
|
|
11285
11321
|
}
|
|
11286
11322
|
return { ctx: env.ctx, params: env.params, ctes, outer: env.outer };
|
|
11287
11323
|
}
|
|
@@ -11340,28 +11376,28 @@ function executeRecursiveCte(env, cte, query) {
|
|
|
11340
11376
|
}
|
|
11341
11377
|
working = next;
|
|
11342
11378
|
}
|
|
11343
|
-
let
|
|
11379
|
+
let rel2 = { columns, rows: result };
|
|
11344
11380
|
if (query.orderBy.length > 0 || query.limit || query.offset) {
|
|
11345
|
-
const sortSpecs = outputOrderSpecs(env,
|
|
11346
|
-
if (sortSpecs.length > 0) sortRows(env,
|
|
11347
|
-
|
|
11381
|
+
const sortSpecs = outputOrderSpecs(env, rel2, query.orderBy);
|
|
11382
|
+
if (sortSpecs.length > 0) sortRows(env, rel2, sortSpecs);
|
|
11383
|
+
rel2 = applyLimitOffset(env, rel2, query.limit, query.offset);
|
|
11348
11384
|
}
|
|
11349
|
-
return
|
|
11385
|
+
return rel2;
|
|
11350
11386
|
}
|
|
11351
|
-
function renameWithAliases(
|
|
11352
|
-
if (colAliases && colAliases.length >
|
|
11387
|
+
function renameWithAliases(rel2, label, colAliases, what) {
|
|
11388
|
+
if (colAliases && colAliases.length > rel2.columns.length) {
|
|
11353
11389
|
throw pgError(
|
|
11354
11390
|
"invalid_column_reference",
|
|
11355
|
-
`table "${what}" has ${
|
|
11391
|
+
`table "${what}" has ${rel2.columns.length} columns available but ${colAliases.length} columns specified`,
|
|
11356
11392
|
"42P10"
|
|
11357
11393
|
);
|
|
11358
11394
|
}
|
|
11359
|
-
const columns =
|
|
11395
|
+
const columns = rel2.columns.map((c, i) => ({
|
|
11360
11396
|
name: colAliases?.[i] ?? c.name,
|
|
11361
11397
|
type: c.type === UNKNOWN ? "text" : c.type,
|
|
11362
11398
|
table: label
|
|
11363
11399
|
}));
|
|
11364
|
-
return { columns, rows:
|
|
11400
|
+
return { columns, rows: rel2.rows };
|
|
11365
11401
|
}
|
|
11366
11402
|
function materializeItem(env, item, scope) {
|
|
11367
11403
|
switch (item.type) {
|
|
@@ -11376,15 +11412,15 @@ function materializeItem(env, item, scope) {
|
|
|
11376
11412
|
const state = env.ctx.state;
|
|
11377
11413
|
const table = state.findTable(item.name);
|
|
11378
11414
|
if (table) {
|
|
11379
|
-
const
|
|
11415
|
+
const rel2 = {
|
|
11380
11416
|
columns: table.columns.map((c) => ({ name: c.name, type: c.type.id, table: label })),
|
|
11381
11417
|
rows: table.rows
|
|
11382
11418
|
};
|
|
11383
|
-
return { rel: renameWithAliases(
|
|
11419
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
11384
11420
|
}
|
|
11385
11421
|
const view = state.findView(item.name);
|
|
11386
11422
|
if (view) {
|
|
11387
|
-
let
|
|
11423
|
+
let rel2;
|
|
11388
11424
|
if (view.materialized) {
|
|
11389
11425
|
if (view.matRows === null || view.matColumns === null) {
|
|
11390
11426
|
throw pgError(
|
|
@@ -11393,23 +11429,23 @@ function materializeItem(env, item, scope) {
|
|
|
11393
11429
|
"55000"
|
|
11394
11430
|
);
|
|
11395
11431
|
}
|
|
11396
|
-
|
|
11432
|
+
rel2 = {
|
|
11397
11433
|
columns: view.matColumns.map((c) => ({ name: c.name, type: c.type, table: label })),
|
|
11398
11434
|
rows: view.matRows
|
|
11399
11435
|
};
|
|
11400
11436
|
} else {
|
|
11401
11437
|
const viewEnv = { ctx: env.ctx, params: null, ctes: /* @__PURE__ */ new Map(), outer: null };
|
|
11402
|
-
|
|
11403
|
-
|
|
11404
|
-
columns:
|
|
11438
|
+
rel2 = executeSelectStmt(viewEnv, view.query);
|
|
11439
|
+
rel2 = {
|
|
11440
|
+
columns: rel2.columns.map((c, i) => ({
|
|
11405
11441
|
name: view.columns?.[i] ?? c.name,
|
|
11406
11442
|
type: c.type,
|
|
11407
11443
|
table: label
|
|
11408
11444
|
})),
|
|
11409
|
-
rows:
|
|
11445
|
+
rows: rel2.rows
|
|
11410
11446
|
};
|
|
11411
11447
|
}
|
|
11412
|
-
return { rel: renameWithAliases(
|
|
11448
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
11413
11449
|
}
|
|
11414
11450
|
const resolved = state.resolveRelationSchema(item.name);
|
|
11415
11451
|
if (resolved) {
|
|
@@ -11422,9 +11458,9 @@ function materializeItem(env, item, scope) {
|
|
|
11422
11458
|
}
|
|
11423
11459
|
case "from_subquery": {
|
|
11424
11460
|
const subEnv = childEnv(env, item.lateral ? scope : env.outer);
|
|
11425
|
-
const
|
|
11461
|
+
const rel2 = executeSelectStmt(subEnv, item.query);
|
|
11426
11462
|
const label = item.alias ?? "unnamed_subquery";
|
|
11427
|
-
return { rel: renameWithAliases(
|
|
11463
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
11428
11464
|
}
|
|
11429
11465
|
case "from_func":
|
|
11430
11466
|
return materializeFunc(env, item, scope);
|
|
@@ -11461,7 +11497,7 @@ function srfCallRelation(env, call, scope, alias) {
|
|
|
11461
11497
|
}
|
|
11462
11498
|
function materializeFunc(env, item, scope) {
|
|
11463
11499
|
const effScope = scope ?? env.outer;
|
|
11464
|
-
let
|
|
11500
|
+
let rel2;
|
|
11465
11501
|
if (item.rowsFrom) {
|
|
11466
11502
|
const parts = item.rowsFrom.map((c) => srfCallRelation(env, c, effScope, null));
|
|
11467
11503
|
const maxLen = Math.max(0, ...parts.map((p) => p.rows.length));
|
|
@@ -11476,18 +11512,18 @@ function materializeFunc(env, item, scope) {
|
|
|
11476
11512
|
}
|
|
11477
11513
|
rows.push(row);
|
|
11478
11514
|
}
|
|
11479
|
-
|
|
11515
|
+
rel2 = { columns, rows };
|
|
11480
11516
|
} else {
|
|
11481
|
-
|
|
11517
|
+
rel2 = srfCallRelation(env, item.call, effScope, item.alias);
|
|
11482
11518
|
}
|
|
11483
11519
|
if (item.withOrdinality) {
|
|
11484
|
-
|
|
11485
|
-
columns: [...
|
|
11486
|
-
rows:
|
|
11520
|
+
rel2 = {
|
|
11521
|
+
columns: [...rel2.columns, { name: "ordinality", type: "int8", table: null }],
|
|
11522
|
+
rows: rel2.rows.map((r, i) => [...r, BigInt(i + 1)])
|
|
11487
11523
|
};
|
|
11488
11524
|
}
|
|
11489
11525
|
const label = item.alias ?? (item.call.type === "func" ? item.call.name[item.call.name.length - 1] : "unnamed_function");
|
|
11490
|
-
return { rel: renameWithAliases(
|
|
11526
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
11491
11527
|
}
|
|
11492
11528
|
function isLateralItem(item) {
|
|
11493
11529
|
switch (item.type) {
|
|
@@ -12016,9 +12052,9 @@ function computeAggregate(env, call, rows) {
|
|
|
12016
12052
|
for (const t of effective) acc.step(t.args);
|
|
12017
12053
|
return acc.result();
|
|
12018
12054
|
}
|
|
12019
|
-
function sortRows(env,
|
|
12055
|
+
function sortRows(env, rel2, specs) {
|
|
12020
12056
|
const ctx = env.ctx;
|
|
12021
|
-
const indexed =
|
|
12057
|
+
const indexed = rel2.rows.map((row, i) => ({ row, i }));
|
|
12022
12058
|
indexed.sort((a, b) => {
|
|
12023
12059
|
for (const s of specs) {
|
|
12024
12060
|
const av = a.row[s.colIdx] ?? null;
|
|
@@ -12030,14 +12066,14 @@ function sortRows(env, rel, specs) {
|
|
|
12030
12066
|
if (c2 !== 0) return c2;
|
|
12031
12067
|
continue;
|
|
12032
12068
|
}
|
|
12033
|
-
const t =
|
|
12069
|
+
const t = rel2.columns[s.colIdx].type;
|
|
12034
12070
|
let c = datumCompare(t === UNKNOWN ? "text" : t, av, bv, ctx);
|
|
12035
12071
|
if (s.dir === "desc") c = -c;
|
|
12036
12072
|
if (c !== 0) return c;
|
|
12037
12073
|
}
|
|
12038
12074
|
return a.i - b.i;
|
|
12039
12075
|
});
|
|
12040
|
-
|
|
12076
|
+
rel2.rows = indexed.map((x) => x.row);
|
|
12041
12077
|
}
|
|
12042
12078
|
function orderDirection(ob) {
|
|
12043
12079
|
let dir = ob.dir ?? "asc";
|
|
@@ -12046,30 +12082,30 @@ function orderDirection(ob) {
|
|
|
12046
12082
|
const nullsFirst = ob.nulls ? ob.nulls === "first" : dir === "desc";
|
|
12047
12083
|
return { dir, nullsFirst };
|
|
12048
12084
|
}
|
|
12049
|
-
function outputOrderSpecs(env,
|
|
12085
|
+
function outputOrderSpecs(env, rel2, orderBy) {
|
|
12050
12086
|
if (orderBy.length === 0) return [];
|
|
12051
12087
|
const specs = [];
|
|
12052
12088
|
const extraCols = [];
|
|
12053
12089
|
const extraExprs = [];
|
|
12054
12090
|
for (const ob of orderBy) {
|
|
12055
12091
|
const { dir, nullsFirst } = orderDirection(ob);
|
|
12056
|
-
const pos = orderPosition(ob.expr,
|
|
12092
|
+
const pos = orderPosition(ob.expr, rel2);
|
|
12057
12093
|
if (pos !== null) {
|
|
12058
12094
|
specs.push({ colIdx: pos, dir, nullsFirst });
|
|
12059
12095
|
continue;
|
|
12060
12096
|
}
|
|
12061
|
-
specs.push({ colIdx:
|
|
12097
|
+
specs.push({ colIdx: rel2.columns.length + extraCols.length, dir, nullsFirst });
|
|
12062
12098
|
extraCols.push({ name: `__ord${extraCols.length}`, type: UNKNOWN, table: null, hidden: true });
|
|
12063
12099
|
extraExprs.push(ob.expr);
|
|
12064
12100
|
}
|
|
12065
12101
|
if (extraExprs.length > 0) {
|
|
12066
|
-
const baseCols =
|
|
12067
|
-
|
|
12068
|
-
|
|
12102
|
+
const baseCols = rel2.columns.slice();
|
|
12103
|
+
rel2.columns = [...rel2.columns, ...extraCols];
|
|
12104
|
+
rel2.rows = rel2.rows.map((row) => {
|
|
12069
12105
|
const scope = new RowScope(baseCols, row, env.outer);
|
|
12070
12106
|
const extras = extraExprs.map((e) => evalScalar(env, scope, e));
|
|
12071
12107
|
for (let k = 0; k < extras.length; k++) {
|
|
12072
|
-
const col =
|
|
12108
|
+
const col = rel2.columns[baseCols.length + k];
|
|
12073
12109
|
col.type = unifyAggType(col.type, extras[k].t);
|
|
12074
12110
|
}
|
|
12075
12111
|
return [...row, ...extras.map((x) => x.v)];
|
|
@@ -12077,8 +12113,8 @@ function outputOrderSpecs(env, rel, orderBy) {
|
|
|
12077
12113
|
}
|
|
12078
12114
|
return specs;
|
|
12079
12115
|
}
|
|
12080
|
-
function orderPosition(e,
|
|
12081
|
-
const visible =
|
|
12116
|
+
function orderPosition(e, rel2) {
|
|
12117
|
+
const visible = rel2.columns.map((c, i) => ({ c, i })).filter(({ c }) => !c.hidden);
|
|
12082
12118
|
if (e.type === "number_lit" && /^\d+$/.test(e.raw)) {
|
|
12083
12119
|
const k = Number(e.raw);
|
|
12084
12120
|
const v = visible[k - 1];
|
|
@@ -12097,16 +12133,16 @@ function orderPosition(e, rel) {
|
|
|
12097
12133
|
}
|
|
12098
12134
|
return null;
|
|
12099
12135
|
}
|
|
12100
|
-
function stripHidden(
|
|
12101
|
-
if (!
|
|
12102
|
-
const keep =
|
|
12136
|
+
function stripHidden(rel2) {
|
|
12137
|
+
if (!rel2.columns.some((c) => c.hidden)) return rel2;
|
|
12138
|
+
const keep = rel2.columns.map((c, i) => ({ c, i })).filter(({ c }) => !c.hidden);
|
|
12103
12139
|
return {
|
|
12104
12140
|
columns: keep.map(({ c }) => c),
|
|
12105
|
-
rows:
|
|
12141
|
+
rows: rel2.rows.map((row) => keep.map(({ i }) => row[i] ?? null))
|
|
12106
12142
|
};
|
|
12107
12143
|
}
|
|
12108
|
-
function applyLimitOffset(env,
|
|
12109
|
-
let rows =
|
|
12144
|
+
function applyLimitOffset(env, rel2, limit, offset, tieSpecs) {
|
|
12145
|
+
let rows = rel2.rows;
|
|
12110
12146
|
if (offset) {
|
|
12111
12147
|
const v = evalScalar(env, env.outer, offset);
|
|
12112
12148
|
if (v.v !== null) {
|
|
@@ -12123,14 +12159,14 @@ function applyLimitOffset(env, rel, limit, offset, tieSpecs) {
|
|
|
12123
12159
|
let end = Math.min(n, rows.length);
|
|
12124
12160
|
if (tieSpecs && end > 0 && end < rows.length) {
|
|
12125
12161
|
const boundary = rows[end - 1];
|
|
12126
|
-
while (end < rows.length && sortKeysEqual(env,
|
|
12162
|
+
while (end < rows.length && sortKeysEqual(env, rel2, tieSpecs, boundary, rows[end])) end++;
|
|
12127
12163
|
}
|
|
12128
12164
|
rows = rows.slice(0, end);
|
|
12129
12165
|
}
|
|
12130
12166
|
}
|
|
12131
|
-
return { columns:
|
|
12167
|
+
return { columns: rel2.columns, rows };
|
|
12132
12168
|
}
|
|
12133
|
-
function sortKeysEqual(env,
|
|
12169
|
+
function sortKeysEqual(env, rel2, specs, a, b) {
|
|
12134
12170
|
for (const s of specs) {
|
|
12135
12171
|
const av = a[s.colIdx] ?? null;
|
|
12136
12172
|
const bv = b[s.colIdx] ?? null;
|
|
@@ -12138,7 +12174,7 @@ function sortKeysEqual(env, rel, specs, a, b) {
|
|
|
12138
12174
|
if (av !== bv) return false;
|
|
12139
12175
|
continue;
|
|
12140
12176
|
}
|
|
12141
|
-
const t =
|
|
12177
|
+
const t = rel2.columns[s.colIdx].type;
|
|
12142
12178
|
if (datumCompare(t === UNKNOWN ? "text" : t, av, bv, env.ctx) !== 0) return false;
|
|
12143
12179
|
}
|
|
12144
12180
|
return true;
|
|
@@ -12197,10 +12233,10 @@ function setOpRelation(env, op) {
|
|
|
12197
12233
|
return t === UNKNOWN ? "text" : t;
|
|
12198
12234
|
});
|
|
12199
12235
|
const columns = left.columns.map((c, i) => ({ name: c.name, type: types[i], table: null }));
|
|
12200
|
-
const normalize = (
|
|
12236
|
+
const normalize = (rel2) => rel2.rows.map(
|
|
12201
12237
|
(row) => row.map((v, i) => {
|
|
12202
12238
|
if (v === null) return null;
|
|
12203
|
-
const srcT =
|
|
12239
|
+
const srcT = rel2.columns[i].type;
|
|
12204
12240
|
if (srcT === types[i]) return v;
|
|
12205
12241
|
return castTo(ctx, tv(srcT === UNKNOWN ? "text" : srcT, v), types[i], {}).v;
|
|
12206
12242
|
})
|
|
@@ -12628,26 +12664,26 @@ function executeCore(env0, core, orderBy) {
|
|
|
12628
12664
|
outRows[r][k] = castTo(ctx, tv(cellT, v), finalT, { explicit: true }).v;
|
|
12629
12665
|
}
|
|
12630
12666
|
}
|
|
12631
|
-
let
|
|
12667
|
+
let rel2 = { columns: outColumns, rows: outRows };
|
|
12632
12668
|
if (sortSpecs.length > 0) {
|
|
12633
|
-
sortRows(env,
|
|
12669
|
+
sortRows(env, rel2, sortSpecs);
|
|
12634
12670
|
}
|
|
12635
12671
|
if (core.distinct) {
|
|
12636
12672
|
if (core.distinct.on) {
|
|
12637
12673
|
const seen = /* @__PURE__ */ new Set();
|
|
12638
|
-
|
|
12674
|
+
rel2.rows = rel2.rows.filter((row) => {
|
|
12639
12675
|
const k = distinctOnIdx.map((ci) => {
|
|
12640
12676
|
const v = row[ci] ?? null;
|
|
12641
|
-
return v === null ? "\0N" : datumKey(
|
|
12677
|
+
return v === null ? "\0N" : datumKey(rel2.columns[ci].type, v);
|
|
12642
12678
|
}).join("");
|
|
12643
12679
|
if (seen.has(k)) return false;
|
|
12644
12680
|
seen.add(k);
|
|
12645
12681
|
return true;
|
|
12646
12682
|
});
|
|
12647
12683
|
} else {
|
|
12648
|
-
const visible =
|
|
12684
|
+
const visible = rel2.columns.map((c, i) => ({ c, i })).filter(({ c }) => !c.hidden);
|
|
12649
12685
|
const seen = /* @__PURE__ */ new Set();
|
|
12650
|
-
|
|
12686
|
+
rel2.rows = rel2.rows.filter((row) => {
|
|
12651
12687
|
const k = visible.map(({ c, i }) => {
|
|
12652
12688
|
const v = row[i] ?? null;
|
|
12653
12689
|
return v === null ? "\0N" : datumKey(c.type, v);
|
|
@@ -12658,28 +12694,28 @@ function executeCore(env0, core, orderBy) {
|
|
|
12658
12694
|
});
|
|
12659
12695
|
}
|
|
12660
12696
|
}
|
|
12661
|
-
|
|
12662
|
-
return
|
|
12697
|
+
rel2 = stripHidden(rel2);
|
|
12698
|
+
return rel2;
|
|
12663
12699
|
}
|
|
12664
12700
|
function executeSelectStmt(env0, stmt) {
|
|
12665
12701
|
const env = applyWith(env0, stmt.with);
|
|
12666
|
-
let
|
|
12702
|
+
let rel2;
|
|
12667
12703
|
if (stmt.body.type === "select_core") {
|
|
12668
|
-
|
|
12704
|
+
rel2 = executeCore(env, stmt.body, stmt.orderBy);
|
|
12669
12705
|
} else {
|
|
12670
|
-
|
|
12671
|
-
const specs = outputOrderSpecs(env,
|
|
12672
|
-
if (specs.length > 0) sortRows(env,
|
|
12673
|
-
|
|
12706
|
+
rel2 = executeBody(env, stmt.body);
|
|
12707
|
+
const specs = outputOrderSpecs(env, rel2, stmt.orderBy);
|
|
12708
|
+
if (specs.length > 0) sortRows(env, rel2, specs);
|
|
12709
|
+
rel2 = stripHidden(rel2);
|
|
12674
12710
|
}
|
|
12675
12711
|
if (stmt.limitWithTies) {
|
|
12676
12712
|
if (stmt.orderBy.length === 0) {
|
|
12677
12713
|
throw pgError("syntax", "WITH TIES cannot be specified without ORDER BY clause", "42601");
|
|
12678
12714
|
}
|
|
12679
|
-
const tieSpecs = outputOrderSpecs(env,
|
|
12680
|
-
return stripHidden(applyLimitOffset(env,
|
|
12715
|
+
const tieSpecs = outputOrderSpecs(env, rel2, stmt.orderBy);
|
|
12716
|
+
return stripHidden(applyLimitOffset(env, rel2, stmt.limit, stmt.offset, tieSpecs));
|
|
12681
12717
|
}
|
|
12682
|
-
return applyLimitOffset(env,
|
|
12718
|
+
return applyLimitOffset(env, rel2, stmt.limit, stmt.offset);
|
|
12683
12719
|
}
|
|
12684
12720
|
|
|
12685
12721
|
// src/constraints/enforce.ts
|
|
@@ -12868,6 +12904,9 @@ function matches(t, event) {
|
|
|
12868
12904
|
return t.events.some((e) => e.event === event);
|
|
12869
12905
|
}
|
|
12870
12906
|
var executor = null;
|
|
12907
|
+
function setTriggerExecutor(e) {
|
|
12908
|
+
executor = e;
|
|
12909
|
+
}
|
|
12871
12910
|
function fireRowTriggers(env, table, timing, event, oldRow, newRow) {
|
|
12872
12911
|
let row = newRow ?? oldRow;
|
|
12873
12912
|
for (const t of table.triggers) {
|
|
@@ -13010,13 +13049,13 @@ function insertSourceRows(env, stmt, colIdxs) {
|
|
|
13010
13049
|
}
|
|
13011
13050
|
return rows;
|
|
13012
13051
|
}
|
|
13013
|
-
const
|
|
13014
|
-
if (
|
|
13052
|
+
const rel2 = executeSelectStmt(env, src);
|
|
13053
|
+
if (rel2.columns.length > colIdxs.length) {
|
|
13015
13054
|
throw pgError("syntax", "INSERT has more expressions than target columns", "42601");
|
|
13016
13055
|
}
|
|
13017
|
-
return
|
|
13056
|
+
return rel2.rows.map(
|
|
13018
13057
|
(r) => r.map((v, i) => {
|
|
13019
|
-
const t =
|
|
13058
|
+
const t = rel2.columns[i].type;
|
|
13020
13059
|
return tv(t === UNKNOWN ? "text" : t, v);
|
|
13021
13060
|
})
|
|
13022
13061
|
);
|
|
@@ -13179,21 +13218,21 @@ function applyUpdateSets(env, table, sets, scope, row) {
|
|
|
13179
13218
|
return i;
|
|
13180
13219
|
});
|
|
13181
13220
|
if (typeof set.value === "object" && "kind" in set.value && set.value.kind === "row_subquery") {
|
|
13182
|
-
const
|
|
13221
|
+
const rel2 = executeSelectStmt(
|
|
13183
13222
|
{ ctx: env.ctx, params: env.params, ctes: env.ctes, outer: scope },
|
|
13184
13223
|
set.value.query
|
|
13185
13224
|
);
|
|
13186
|
-
if (
|
|
13225
|
+
if (rel2.rows.length > 1) {
|
|
13187
13226
|
throw pgError(
|
|
13188
13227
|
"cardinality_violation",
|
|
13189
13228
|
"more than one row returned by a subquery used as an expression",
|
|
13190
13229
|
"21000"
|
|
13191
13230
|
);
|
|
13192
13231
|
}
|
|
13193
|
-
const srcRow =
|
|
13232
|
+
const srcRow = rel2.rows[0] ?? null;
|
|
13194
13233
|
for (let k = 0; k < colIdxs.length; k++) {
|
|
13195
13234
|
const col2 = table.columns[colIdxs[k]];
|
|
13196
|
-
const v = srcRow === null ? tv(col2.type.id, null) : tv(
|
|
13235
|
+
const v = srcRow === null ? tv(col2.type.id, null) : tv(rel2.columns[k]?.type ?? "text", srcRow[k] ?? null);
|
|
13197
13236
|
row[colIdxs[k]] = coerceToColumn(env, v.t === UNKNOWN ? tv("text", v.v) : v, col2);
|
|
13198
13237
|
}
|
|
13199
13238
|
continue;
|
|
@@ -17851,6 +17890,1097 @@ function resolveClock(now) {
|
|
|
17851
17890
|
// src/runtime/options.ts
|
|
17852
17891
|
var DEFAULT_DATABASE_SEED = 1;
|
|
17853
17892
|
|
|
17893
|
+
// src/schema/catalog-tables.ts
|
|
17894
|
+
function rel(specs, rows, table) {
|
|
17895
|
+
const columns = specs.map(([name, type]) => ({ name, type, table }));
|
|
17896
|
+
return { columns, rows };
|
|
17897
|
+
}
|
|
17898
|
+
var OWNER = "postgres";
|
|
17899
|
+
function* allTables(state) {
|
|
17900
|
+
for (const schema of state.schemas.values()) {
|
|
17901
|
+
for (const t of schema.tables.values()) yield t;
|
|
17902
|
+
}
|
|
17903
|
+
}
|
|
17904
|
+
function* allSequences(state) {
|
|
17905
|
+
for (const schema of state.schemas.values()) {
|
|
17906
|
+
for (const s of schema.sequences.values()) yield s;
|
|
17907
|
+
}
|
|
17908
|
+
}
|
|
17909
|
+
var NS_PG_CATALOG = 11;
|
|
17910
|
+
var NS_INFORMATION_SCHEMA = 13212;
|
|
17911
|
+
function namespaceOid(state, name) {
|
|
17912
|
+
if (name === "pg_catalog") return NS_PG_CATALOG;
|
|
17913
|
+
if (name === "information_schema") return NS_INFORMATION_SCHEMA;
|
|
17914
|
+
return state.schemas.get(name)?.oid ?? 0;
|
|
17915
|
+
}
|
|
17916
|
+
function attTypmod(mod, type) {
|
|
17917
|
+
if (!mod || mod.a === void 0) return -1;
|
|
17918
|
+
if (type === "numeric") return (mod.a << 16 | (mod.b ?? 0)) + 4;
|
|
17919
|
+
if (type === "varchar" || type === "bpchar") return mod.a + 4;
|
|
17920
|
+
return mod.a;
|
|
17921
|
+
}
|
|
17922
|
+
function enumOid(ctx, t) {
|
|
17923
|
+
if (!isEnumType(t)) return typeOid(t);
|
|
17924
|
+
const e = ctx.state.findEnumByKey(t.slice(5));
|
|
17925
|
+
return e ? e.oid : 0;
|
|
17926
|
+
}
|
|
17927
|
+
function pgNamespace(state) {
|
|
17928
|
+
const rows = [
|
|
17929
|
+
[NS_PG_CATALOG, "pg_catalog", 10, null],
|
|
17930
|
+
[NS_INFORMATION_SCHEMA, "information_schema", 10, null]
|
|
17931
|
+
];
|
|
17932
|
+
for (const s of state.schemas.values()) rows.push([s.oid, s.name, 10, null]);
|
|
17933
|
+
return rel(
|
|
17934
|
+
[
|
|
17935
|
+
["oid", "oid"],
|
|
17936
|
+
["nspname", "name"],
|
|
17937
|
+
["nspowner", "oid"],
|
|
17938
|
+
["nspacl", "text[]"]
|
|
17939
|
+
],
|
|
17940
|
+
rows,
|
|
17941
|
+
"pg_namespace"
|
|
17942
|
+
);
|
|
17943
|
+
}
|
|
17944
|
+
function pgClass(ctx) {
|
|
17945
|
+
const state = ctx.state;
|
|
17946
|
+
const rows = [];
|
|
17947
|
+
const push = (oid, name, schema, kind, natts, tuples, hasindex, populated, temp) => {
|
|
17948
|
+
rows.push([
|
|
17949
|
+
oid,
|
|
17950
|
+
name,
|
|
17951
|
+
namespaceOid(state, schema),
|
|
17952
|
+
0,
|
|
17953
|
+
10,
|
|
17954
|
+
kind === "i" ? 403 : kind === "S" || kind === "v" ? 0 : 2,
|
|
17955
|
+
oid,
|
|
17956
|
+
0,
|
|
17957
|
+
0,
|
|
17958
|
+
tuples,
|
|
17959
|
+
0,
|
|
17960
|
+
0,
|
|
17961
|
+
hasindex,
|
|
17962
|
+
false,
|
|
17963
|
+
temp ? "t" : "p",
|
|
17964
|
+
kind,
|
|
17965
|
+
natts,
|
|
17966
|
+
0,
|
|
17967
|
+
false,
|
|
17968
|
+
false,
|
|
17969
|
+
false,
|
|
17970
|
+
false,
|
|
17971
|
+
false,
|
|
17972
|
+
populated,
|
|
17973
|
+
kind === "r" ? "d" : "n",
|
|
17974
|
+
false,
|
|
17975
|
+
0,
|
|
17976
|
+
null,
|
|
17977
|
+
null,
|
|
17978
|
+
null
|
|
17979
|
+
]);
|
|
17980
|
+
};
|
|
17981
|
+
for (const schemaData of state.schemas.values()) {
|
|
17982
|
+
for (const t of schemaData.tables.values()) {
|
|
17983
|
+
const hasIndex = t.constraints.some((c) => c.kind === "primary_key" || c.kind === "unique") || [...schemaData.indexes.values()].some((i) => i.table === t.name);
|
|
17984
|
+
push(t.oid, t.name, t.schema, "r", t.columns.length, t.rows.length, hasIndex, true, t.temp);
|
|
17985
|
+
}
|
|
17986
|
+
for (const v of schemaData.views.values()) {
|
|
17987
|
+
push(
|
|
17988
|
+
v.oid,
|
|
17989
|
+
v.name,
|
|
17990
|
+
v.schema,
|
|
17991
|
+
v.materialized ? "m" : "v",
|
|
17992
|
+
v.columns?.length ?? 0,
|
|
17993
|
+
v.matRows?.length ?? 0,
|
|
17994
|
+
false,
|
|
17995
|
+
!v.materialized || v.matRows !== null,
|
|
17996
|
+
v.temp
|
|
17997
|
+
);
|
|
17998
|
+
}
|
|
17999
|
+
for (const s of schemaData.sequences.values()) push(s.oid, s.name, s.schema, "S", 3, 1, false, true, s.temp);
|
|
18000
|
+
for (const i of schemaData.indexes.values()) {
|
|
18001
|
+
push(
|
|
18002
|
+
state.schemas.get(i.schema)?.tables.get(i.table)?.oid ?? 0,
|
|
18003
|
+
i.name,
|
|
18004
|
+
i.schema,
|
|
18005
|
+
"i",
|
|
18006
|
+
i.columns.length,
|
|
18007
|
+
0,
|
|
18008
|
+
false,
|
|
18009
|
+
true,
|
|
18010
|
+
false
|
|
18011
|
+
);
|
|
18012
|
+
}
|
|
18013
|
+
}
|
|
18014
|
+
return rel(
|
|
18015
|
+
[
|
|
18016
|
+
["oid", "oid"],
|
|
18017
|
+
["relname", "name"],
|
|
18018
|
+
["relnamespace", "oid"],
|
|
18019
|
+
["reltype", "oid"],
|
|
18020
|
+
["relowner", "oid"],
|
|
18021
|
+
["relam", "oid"],
|
|
18022
|
+
["relfilenode", "oid"],
|
|
18023
|
+
["reltablespace", "oid"],
|
|
18024
|
+
["relpages", "int4"],
|
|
18025
|
+
["reltuples", "float4"],
|
|
18026
|
+
["relallvisible", "int4"],
|
|
18027
|
+
["reltoastrelid", "oid"],
|
|
18028
|
+
["relhasindex", "bool"],
|
|
18029
|
+
["relisshared", "bool"],
|
|
18030
|
+
["relpersistence", "bpchar"],
|
|
18031
|
+
["relkind", "bpchar"],
|
|
18032
|
+
["relnatts", "int2"],
|
|
18033
|
+
["relchecks", "int2"],
|
|
18034
|
+
["relhasrules", "bool"],
|
|
18035
|
+
["relhastriggers", "bool"],
|
|
18036
|
+
["relhassubclass", "bool"],
|
|
18037
|
+
["relrowsecurity", "bool"],
|
|
18038
|
+
["relforcerowsecurity", "bool"],
|
|
18039
|
+
["relispopulated", "bool"],
|
|
18040
|
+
["relreplident", "bpchar"],
|
|
18041
|
+
["relispartition", "bool"],
|
|
18042
|
+
["relrewrite", "oid"],
|
|
18043
|
+
["relacl", "text[]"],
|
|
18044
|
+
["reloptions", "text[]"],
|
|
18045
|
+
["relpartbound", "text"]
|
|
18046
|
+
],
|
|
18047
|
+
rows,
|
|
18048
|
+
"pg_class"
|
|
18049
|
+
);
|
|
18050
|
+
}
|
|
18051
|
+
function pgAttribute(ctx) {
|
|
18052
|
+
const rows = [];
|
|
18053
|
+
for (const t of allTables(ctx.state)) {
|
|
18054
|
+
t.columns.forEach((c, i) => {
|
|
18055
|
+
rows.push([
|
|
18056
|
+
t.oid,
|
|
18057
|
+
c.name,
|
|
18058
|
+
enumOid(ctx, c.type.id),
|
|
18059
|
+
i + 1,
|
|
18060
|
+
attTypmod(c.type.mod, c.type.id),
|
|
18061
|
+
-1,
|
|
18062
|
+
c.notNull,
|
|
18063
|
+
c.defaultExpr !== null || c.identity !== null,
|
|
18064
|
+
false,
|
|
18065
|
+
c.identity ? c.identity.always ? "a" : "d" : "",
|
|
18066
|
+
c.generated ? "s" : "",
|
|
18067
|
+
isArrayType(c.type.id) ? 1 : 0
|
|
18068
|
+
]);
|
|
18069
|
+
});
|
|
18070
|
+
}
|
|
18071
|
+
return rel(
|
|
18072
|
+
[
|
|
18073
|
+
["attrelid", "oid"],
|
|
18074
|
+
["attname", "name"],
|
|
18075
|
+
["atttypid", "oid"],
|
|
18076
|
+
["attnum", "int2"],
|
|
18077
|
+
["atttypmod", "int4"],
|
|
18078
|
+
["attlen", "int2"],
|
|
18079
|
+
["attnotnull", "bool"],
|
|
18080
|
+
["atthasdef", "bool"],
|
|
18081
|
+
["attisdropped", "bool"],
|
|
18082
|
+
["attidentity", "bpchar"],
|
|
18083
|
+
["attgenerated", "bpchar"],
|
|
18084
|
+
["attndims", "int2"]
|
|
18085
|
+
],
|
|
18086
|
+
rows,
|
|
18087
|
+
"pg_attribute"
|
|
18088
|
+
);
|
|
18089
|
+
}
|
|
18090
|
+
function pgType(ctx) {
|
|
18091
|
+
const rows = [];
|
|
18092
|
+
for (const [name, oid] of Object.entries(TYPE_OIDS)) {
|
|
18093
|
+
const isArr = name.startsWith("_");
|
|
18094
|
+
rows.push([
|
|
18095
|
+
oid,
|
|
18096
|
+
name,
|
|
18097
|
+
NS_PG_CATALOG,
|
|
18098
|
+
"b",
|
|
18099
|
+
isArr ? "A" : "U",
|
|
18100
|
+
isArr ? TYPE_OIDS[name.slice(1)] ?? 0 : 0,
|
|
18101
|
+
isArr ? 0 : TYPE_OIDS[`_${name}`] ?? 0,
|
|
18102
|
+
0,
|
|
18103
|
+
0,
|
|
18104
|
+
-1
|
|
18105
|
+
]);
|
|
18106
|
+
}
|
|
18107
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18108
|
+
for (const e of schema.enums.values()) {
|
|
18109
|
+
rows.push([e.oid, e.name, namespaceOid(ctx.state, e.schema), "e", "E", 0, 0, 0, 0, 4]);
|
|
18110
|
+
}
|
|
18111
|
+
for (const d of schema.domains.values()) {
|
|
18112
|
+
rows.push([d.oid, d.name, namespaceOid(ctx.state, d.schema), "d", "S", 0, 0, typeOid(d.baseType.id), 0, -1]);
|
|
18113
|
+
}
|
|
18114
|
+
}
|
|
18115
|
+
return rel(
|
|
18116
|
+
[
|
|
18117
|
+
["oid", "oid"],
|
|
18118
|
+
["typname", "name"],
|
|
18119
|
+
["typnamespace", "oid"],
|
|
18120
|
+
["typtype", "bpchar"],
|
|
18121
|
+
["typcategory", "bpchar"],
|
|
18122
|
+
["typelem", "oid"],
|
|
18123
|
+
["typarray", "oid"],
|
|
18124
|
+
["typbasetype", "oid"],
|
|
18125
|
+
["typrelid", "oid"],
|
|
18126
|
+
["typlen", "int2"]
|
|
18127
|
+
],
|
|
18128
|
+
rows,
|
|
18129
|
+
"pg_type"
|
|
18130
|
+
);
|
|
18131
|
+
}
|
|
18132
|
+
function pgProc(ctx) {
|
|
18133
|
+
const rows = [];
|
|
18134
|
+
let oid = 1e3;
|
|
18135
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18136
|
+
const push = (name, ns, kind, retset, nargs, realOid) => {
|
|
18137
|
+
rows.push([realOid ?? oid++, name, ns, kind, retset, nargs]);
|
|
18138
|
+
};
|
|
18139
|
+
for (const name of getScalarFunctions().keys()) {
|
|
18140
|
+
if (!seen.has(name)) {
|
|
18141
|
+
seen.add(name);
|
|
18142
|
+
push(name, NS_PG_CATALOG, "f", false, -1);
|
|
18143
|
+
}
|
|
18144
|
+
}
|
|
18145
|
+
for (const name of Object.keys(getAggregateFactories())) {
|
|
18146
|
+
if (!seen.has(`agg:${name}`)) {
|
|
18147
|
+
seen.add(`agg:${name}`);
|
|
18148
|
+
push(name, NS_PG_CATALOG, "a", false, -1);
|
|
18149
|
+
}
|
|
18150
|
+
}
|
|
18151
|
+
for (const name of WINDOW_FUNCTION_NAMES) push(name, NS_PG_CATALOG, "w", false, -1);
|
|
18152
|
+
for (const name of getSrfFunctions().keys()) push(name, NS_PG_CATALOG, "f", true, -1);
|
|
18153
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18154
|
+
for (const fns of schema.functions.values()) {
|
|
18155
|
+
for (const f of fns) {
|
|
18156
|
+
push(f.name, namespaceOid(ctx.state, f.schema), "f", f.returnsSet, f.argTypes.length, f.oid);
|
|
18157
|
+
}
|
|
18158
|
+
}
|
|
18159
|
+
}
|
|
18160
|
+
return rel(
|
|
18161
|
+
[
|
|
18162
|
+
["oid", "oid"],
|
|
18163
|
+
["proname", "name"],
|
|
18164
|
+
["pronamespace", "oid"],
|
|
18165
|
+
["prokind", "bpchar"],
|
|
18166
|
+
["proretset", "bool"],
|
|
18167
|
+
["pronargs", "int2"]
|
|
18168
|
+
],
|
|
18169
|
+
rows,
|
|
18170
|
+
"pg_proc"
|
|
18171
|
+
);
|
|
18172
|
+
}
|
|
18173
|
+
function pgEnum(ctx) {
|
|
18174
|
+
const rows = [];
|
|
18175
|
+
let oid = 2e4;
|
|
18176
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18177
|
+
for (const e of schema.enums.values()) {
|
|
18178
|
+
e.labels.forEach((label, i) => {
|
|
18179
|
+
rows.push([oid++, e.oid, i + 1, label]);
|
|
18180
|
+
});
|
|
18181
|
+
}
|
|
18182
|
+
}
|
|
18183
|
+
return rel(
|
|
18184
|
+
[
|
|
18185
|
+
["oid", "oid"],
|
|
18186
|
+
["enumtypid", "oid"],
|
|
18187
|
+
["enumsortorder", "float4"],
|
|
18188
|
+
["enumlabel", "name"]
|
|
18189
|
+
],
|
|
18190
|
+
rows,
|
|
18191
|
+
"pg_enum"
|
|
18192
|
+
);
|
|
18193
|
+
}
|
|
18194
|
+
function pgConstraint(ctx) {
|
|
18195
|
+
const rows = [];
|
|
18196
|
+
let oid = 3e4;
|
|
18197
|
+
for (const t of allTables(ctx.state)) {
|
|
18198
|
+
for (const c of t.constraints) {
|
|
18199
|
+
const contype = c.kind === "primary_key" ? "p" : c.kind === "unique" ? "u" : c.kind === "check" ? "c" : "f";
|
|
18200
|
+
const refTable = c.kind === "foreign_key" ? ctx.state.schemas.get(c.refSchema)?.tables.get(c.refTable) : void 0;
|
|
18201
|
+
rows.push([oid++, c.name, namespaceOid(ctx.state, t.schema), contype, false, false, t.oid, refTable?.oid ?? 0]);
|
|
18202
|
+
}
|
|
18203
|
+
for (const col of t.columns) {
|
|
18204
|
+
if (col.notNull) {
|
|
18205
|
+
rows.push([
|
|
18206
|
+
oid++,
|
|
18207
|
+
`${t.name}_${col.name}_not_null`,
|
|
18208
|
+
namespaceOid(ctx.state, t.schema),
|
|
18209
|
+
"n",
|
|
18210
|
+
false,
|
|
18211
|
+
false,
|
|
18212
|
+
t.oid,
|
|
18213
|
+
0
|
|
18214
|
+
]);
|
|
18215
|
+
}
|
|
18216
|
+
}
|
|
18217
|
+
}
|
|
18218
|
+
return rel(
|
|
18219
|
+
[
|
|
18220
|
+
["oid", "oid"],
|
|
18221
|
+
["conname", "name"],
|
|
18222
|
+
["connamespace", "oid"],
|
|
18223
|
+
["contype", "bpchar"],
|
|
18224
|
+
["condeferrable", "bool"],
|
|
18225
|
+
["condeferred", "bool"],
|
|
18226
|
+
["conrelid", "oid"],
|
|
18227
|
+
["confrelid", "oid"]
|
|
18228
|
+
],
|
|
18229
|
+
rows,
|
|
18230
|
+
"pg_constraint"
|
|
18231
|
+
);
|
|
18232
|
+
}
|
|
18233
|
+
function pgIndex(ctx) {
|
|
18234
|
+
const rows = [];
|
|
18235
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18236
|
+
for (const i of schema.indexes.values()) {
|
|
18237
|
+
const table = schema.tables.get(i.table);
|
|
18238
|
+
const isPrimary = i.isConstraint && table?.constraints.some((c) => c.kind === "primary_key" && c.name === i.name) === true;
|
|
18239
|
+
rows.push([table?.oid ?? 0, table?.oid ?? 0, i.columns.length, i.unique, isPrimary, i.where !== null]);
|
|
18240
|
+
}
|
|
18241
|
+
}
|
|
18242
|
+
return rel(
|
|
18243
|
+
[
|
|
18244
|
+
["indexrelid", "oid"],
|
|
18245
|
+
["indrelid", "oid"],
|
|
18246
|
+
["indnatts", "int2"],
|
|
18247
|
+
["indisunique", "bool"],
|
|
18248
|
+
["indisprimary", "bool"],
|
|
18249
|
+
["indpred", "bool"]
|
|
18250
|
+
],
|
|
18251
|
+
rows,
|
|
18252
|
+
"pg_index"
|
|
18253
|
+
);
|
|
18254
|
+
}
|
|
18255
|
+
function pgSequence(ctx) {
|
|
18256
|
+
const rows = [];
|
|
18257
|
+
for (const s of allSequences(ctx.state)) {
|
|
18258
|
+
rows.push([s.oid, typeOid(s.dataType), s.startValue, s.increment, s.maxValue, s.minValue, s.cache, s.cycle]);
|
|
18259
|
+
}
|
|
18260
|
+
return rel(
|
|
18261
|
+
[
|
|
18262
|
+
["seqrelid", "oid"],
|
|
18263
|
+
["seqtypid", "oid"],
|
|
18264
|
+
["seqstart", "int8"],
|
|
18265
|
+
["seqincrement", "int8"],
|
|
18266
|
+
["seqmax", "int8"],
|
|
18267
|
+
["seqmin", "int8"],
|
|
18268
|
+
["seqcache", "int8"],
|
|
18269
|
+
["seqcycle", "bool"]
|
|
18270
|
+
],
|
|
18271
|
+
rows,
|
|
18272
|
+
"pg_sequence"
|
|
18273
|
+
);
|
|
18274
|
+
}
|
|
18275
|
+
function pgSequencesView(ctx) {
|
|
18276
|
+
const rows = [];
|
|
18277
|
+
for (const s of allSequences(ctx.state)) {
|
|
18278
|
+
rows.push([
|
|
18279
|
+
s.schema,
|
|
18280
|
+
s.name,
|
|
18281
|
+
OWNER,
|
|
18282
|
+
typeDisplayName(s.dataType),
|
|
18283
|
+
s.startValue,
|
|
18284
|
+
s.minValue,
|
|
18285
|
+
s.maxValue,
|
|
18286
|
+
s.increment,
|
|
18287
|
+
s.cycle,
|
|
18288
|
+
s.cache,
|
|
18289
|
+
s.isCalled ? s.lastValue : null
|
|
18290
|
+
]);
|
|
18291
|
+
}
|
|
18292
|
+
return rel(
|
|
18293
|
+
[
|
|
18294
|
+
["schemaname", "name"],
|
|
18295
|
+
["sequencename", "name"],
|
|
18296
|
+
["sequenceowner", "name"],
|
|
18297
|
+
["data_type", "text"],
|
|
18298
|
+
["start_value", "int8"],
|
|
18299
|
+
["min_value", "int8"],
|
|
18300
|
+
["max_value", "int8"],
|
|
18301
|
+
["increment_by", "int8"],
|
|
18302
|
+
["cycle", "bool"],
|
|
18303
|
+
["cache_size", "int8"],
|
|
18304
|
+
["last_value", "int8"]
|
|
18305
|
+
],
|
|
18306
|
+
rows,
|
|
18307
|
+
"pg_sequences"
|
|
18308
|
+
);
|
|
18309
|
+
}
|
|
18310
|
+
function pgTables(ctx) {
|
|
18311
|
+
const rows = [];
|
|
18312
|
+
for (const t of allTables(ctx.state)) {
|
|
18313
|
+
const hasIndexes = t.constraints.some((c) => c.kind === "primary_key" || c.kind === "unique") || [...ctx.state.schemas.get(t.schema)?.indexes.values() ?? []].some((i) => i.table === t.name);
|
|
18314
|
+
rows.push([t.schema, t.name, OWNER, null, hasIndexes, false, t.triggers.length > 0, false]);
|
|
18315
|
+
}
|
|
18316
|
+
return rel(
|
|
18317
|
+
[
|
|
18318
|
+
["schemaname", "name"],
|
|
18319
|
+
["tablename", "name"],
|
|
18320
|
+
["tableowner", "name"],
|
|
18321
|
+
["tablespace", "name"],
|
|
18322
|
+
["hasindexes", "bool"],
|
|
18323
|
+
["hasrules", "bool"],
|
|
18324
|
+
["hastriggers", "bool"],
|
|
18325
|
+
["rowsecurity", "bool"]
|
|
18326
|
+
],
|
|
18327
|
+
rows,
|
|
18328
|
+
"pg_tables"
|
|
18329
|
+
);
|
|
18330
|
+
}
|
|
18331
|
+
function pgViews(ctx, materialized) {
|
|
18332
|
+
const rows = [];
|
|
18333
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18334
|
+
for (const v of schema.views.values()) {
|
|
18335
|
+
if (v.materialized !== materialized) continue;
|
|
18336
|
+
if (materialized) rows.push([v.schema, v.name, OWNER, null, v.matRows !== null, null]);
|
|
18337
|
+
else rows.push([v.schema, v.name, OWNER, null]);
|
|
18338
|
+
}
|
|
18339
|
+
}
|
|
18340
|
+
if (materialized) {
|
|
18341
|
+
return rel(
|
|
18342
|
+
[
|
|
18343
|
+
["schemaname", "name"],
|
|
18344
|
+
["matviewname", "name"],
|
|
18345
|
+
["matviewowner", "name"],
|
|
18346
|
+
["tablespace", "name"],
|
|
18347
|
+
["ispopulated", "bool"],
|
|
18348
|
+
["definition", "text"]
|
|
18349
|
+
],
|
|
18350
|
+
rows,
|
|
18351
|
+
"pg_matviews"
|
|
18352
|
+
);
|
|
18353
|
+
}
|
|
18354
|
+
return rel(
|
|
18355
|
+
[
|
|
18356
|
+
["schemaname", "name"],
|
|
18357
|
+
["viewname", "name"],
|
|
18358
|
+
["viewowner", "name"],
|
|
18359
|
+
["definition", "text"]
|
|
18360
|
+
],
|
|
18361
|
+
rows,
|
|
18362
|
+
"pg_views"
|
|
18363
|
+
);
|
|
18364
|
+
}
|
|
18365
|
+
function pgIndexesView(ctx) {
|
|
18366
|
+
const rows = [];
|
|
18367
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18368
|
+
for (const i of schema.indexes.values()) {
|
|
18369
|
+
rows.push([i.schema, i.table, i.name, null, null]);
|
|
18370
|
+
}
|
|
18371
|
+
}
|
|
18372
|
+
return rel(
|
|
18373
|
+
[
|
|
18374
|
+
["schemaname", "name"],
|
|
18375
|
+
["tablename", "name"],
|
|
18376
|
+
["indexname", "name"],
|
|
18377
|
+
["tablespace", "name"],
|
|
18378
|
+
["indexdef", "text"]
|
|
18379
|
+
],
|
|
18380
|
+
rows,
|
|
18381
|
+
"pg_indexes"
|
|
18382
|
+
);
|
|
18383
|
+
}
|
|
18384
|
+
function pgSettings(ctx) {
|
|
18385
|
+
const rows = [];
|
|
18386
|
+
const keys = /* @__PURE__ */ new Set([...ctx.state.settings.keys(), ...ctx.state.localSettings.keys()]);
|
|
18387
|
+
for (const name of [...keys].sort()) {
|
|
18388
|
+
rows.push([name, ctx.state.getSetting(name) ?? null]);
|
|
18389
|
+
}
|
|
18390
|
+
return rel(
|
|
18391
|
+
[
|
|
18392
|
+
["name", "text"],
|
|
18393
|
+
["setting", "text"]
|
|
18394
|
+
],
|
|
18395
|
+
rows,
|
|
18396
|
+
"pg_settings"
|
|
18397
|
+
);
|
|
18398
|
+
}
|
|
18399
|
+
function pgDatabase() {
|
|
18400
|
+
return rel(
|
|
18401
|
+
[
|
|
18402
|
+
["oid", "oid"],
|
|
18403
|
+
["datname", "name"],
|
|
18404
|
+
["encoding", "int4"],
|
|
18405
|
+
["datistemplate", "bool"],
|
|
18406
|
+
["datallowconn", "bool"]
|
|
18407
|
+
],
|
|
18408
|
+
[[5, "postgres", 6, false, true]],
|
|
18409
|
+
"pg_database"
|
|
18410
|
+
);
|
|
18411
|
+
}
|
|
18412
|
+
function pgRoles() {
|
|
18413
|
+
return rel(
|
|
18414
|
+
[
|
|
18415
|
+
["oid", "oid"],
|
|
18416
|
+
["rolname", "name"],
|
|
18417
|
+
["rolsuper", "bool"],
|
|
18418
|
+
["rolcanlogin", "bool"]
|
|
18419
|
+
],
|
|
18420
|
+
[[10, OWNER, true, true]],
|
|
18421
|
+
"pg_roles"
|
|
18422
|
+
);
|
|
18423
|
+
}
|
|
18424
|
+
function pgTrigger(ctx) {
|
|
18425
|
+
const rows = [];
|
|
18426
|
+
let oid = 4e4;
|
|
18427
|
+
for (const t of allTables(ctx.state)) {
|
|
18428
|
+
for (const tr of t.triggers) {
|
|
18429
|
+
rows.push([oid++, tr.name, t.oid, !tr.forEachRow]);
|
|
18430
|
+
}
|
|
18431
|
+
}
|
|
18432
|
+
return rel(
|
|
18433
|
+
[
|
|
18434
|
+
["oid", "oid"],
|
|
18435
|
+
["tgname", "name"],
|
|
18436
|
+
["tgrelid", "oid"],
|
|
18437
|
+
["tgisinternal", "bool"]
|
|
18438
|
+
],
|
|
18439
|
+
rows,
|
|
18440
|
+
"pg_trigger"
|
|
18441
|
+
);
|
|
18442
|
+
}
|
|
18443
|
+
var CATALOG_NAME = "postgres";
|
|
18444
|
+
function infoSchemata(state) {
|
|
18445
|
+
const rows = [
|
|
18446
|
+
[CATALOG_NAME, "pg_catalog", OWNER],
|
|
18447
|
+
[CATALOG_NAME, "information_schema", OWNER]
|
|
18448
|
+
];
|
|
18449
|
+
for (const s of state.schemas.values()) rows.push([CATALOG_NAME, s.name, OWNER]);
|
|
18450
|
+
return rel(
|
|
18451
|
+
[
|
|
18452
|
+
["catalog_name", "name"],
|
|
18453
|
+
["schema_name", "name"],
|
|
18454
|
+
["schema_owner", "name"]
|
|
18455
|
+
],
|
|
18456
|
+
rows,
|
|
18457
|
+
"schemata"
|
|
18458
|
+
);
|
|
18459
|
+
}
|
|
18460
|
+
function infoTables(ctx) {
|
|
18461
|
+
const rows = [];
|
|
18462
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18463
|
+
for (const t of schema.tables.values()) {
|
|
18464
|
+
rows.push([CATALOG_NAME, t.schema, t.name, t.temp ? "LOCAL TEMPORARY" : "BASE TABLE", "YES"]);
|
|
18465
|
+
}
|
|
18466
|
+
for (const v of schema.views.values()) {
|
|
18467
|
+
if (!v.materialized) rows.push([CATALOG_NAME, v.schema, v.name, "VIEW", "NO"]);
|
|
18468
|
+
}
|
|
18469
|
+
}
|
|
18470
|
+
return rel(
|
|
18471
|
+
[
|
|
18472
|
+
["table_catalog", "name"],
|
|
18473
|
+
["table_schema", "name"],
|
|
18474
|
+
["table_name", "name"],
|
|
18475
|
+
["table_type", "text"],
|
|
18476
|
+
["is_insertable_into", "text"]
|
|
18477
|
+
],
|
|
18478
|
+
rows,
|
|
18479
|
+
"tables"
|
|
18480
|
+
);
|
|
18481
|
+
}
|
|
18482
|
+
function infoColumns(ctx) {
|
|
18483
|
+
const rows = [];
|
|
18484
|
+
for (const t of allTables(ctx.state)) {
|
|
18485
|
+
t.columns.forEach((c, i) => {
|
|
18486
|
+
const id = c.type.id;
|
|
18487
|
+
const isNumeric2 = id === "numeric";
|
|
18488
|
+
const isIntish = id === "int2" || id === "int4" || id === "int8";
|
|
18489
|
+
const charMax = (id === "varchar" || id === "bpchar") && c.type.mod?.a !== void 0 ? c.type.mod.a : null;
|
|
18490
|
+
const dataType = isArrayType(id) ? "ARRAY" : isEnumType(id) ? "USER-DEFINED" : typeDisplayName(id);
|
|
18491
|
+
const udt = isArrayType(id) ? `_${arrayUdt(id)}` : isEnumType(id) ? id.slice(5).split(".").pop() : id;
|
|
18492
|
+
rows.push([
|
|
18493
|
+
CATALOG_NAME,
|
|
18494
|
+
t.schema,
|
|
18495
|
+
t.name,
|
|
18496
|
+
c.name,
|
|
18497
|
+
i + 1,
|
|
18498
|
+
null,
|
|
18499
|
+
c.notNull ? "NO" : "YES",
|
|
18500
|
+
dataType,
|
|
18501
|
+
charMax,
|
|
18502
|
+
isNumeric2 ? c.type.mod?.a ?? null : isIntish ? id === "int2" ? 16 : id === "int4" ? 32 : 64 : null,
|
|
18503
|
+
isNumeric2 ? c.type.mod?.b ?? null : isIntish ? 0 : null,
|
|
18504
|
+
udt,
|
|
18505
|
+
c.identity ? "YES" : "NO",
|
|
18506
|
+
c.generated ? "ALWAYS" : "NEVER",
|
|
18507
|
+
"YES"
|
|
18508
|
+
]);
|
|
18509
|
+
});
|
|
18510
|
+
}
|
|
18511
|
+
return rel(
|
|
18512
|
+
[
|
|
18513
|
+
["table_catalog", "name"],
|
|
18514
|
+
["table_schema", "name"],
|
|
18515
|
+
["table_name", "name"],
|
|
18516
|
+
["column_name", "name"],
|
|
18517
|
+
["ordinal_position", "int4"],
|
|
18518
|
+
["column_default", "text"],
|
|
18519
|
+
["is_nullable", "text"],
|
|
18520
|
+
["data_type", "text"],
|
|
18521
|
+
["character_maximum_length", "int4"],
|
|
18522
|
+
["numeric_precision", "int4"],
|
|
18523
|
+
["numeric_scale", "int4"],
|
|
18524
|
+
["udt_name", "name"],
|
|
18525
|
+
["is_identity", "text"],
|
|
18526
|
+
["is_generated", "text"],
|
|
18527
|
+
["is_updatable", "text"]
|
|
18528
|
+
],
|
|
18529
|
+
rows,
|
|
18530
|
+
"columns"
|
|
18531
|
+
);
|
|
18532
|
+
}
|
|
18533
|
+
function arrayUdt(t) {
|
|
18534
|
+
const elem = t.slice(0, -2);
|
|
18535
|
+
return isEnumType(elem) ? elem.slice(5).split(".").pop() : elem;
|
|
18536
|
+
}
|
|
18537
|
+
function infoViews(ctx) {
|
|
18538
|
+
const rows = [];
|
|
18539
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18540
|
+
for (const v of schema.views.values()) {
|
|
18541
|
+
if (!v.materialized) rows.push([CATALOG_NAME, v.schema, v.name, null]);
|
|
18542
|
+
}
|
|
18543
|
+
}
|
|
18544
|
+
return rel(
|
|
18545
|
+
[
|
|
18546
|
+
["table_catalog", "name"],
|
|
18547
|
+
["table_schema", "name"],
|
|
18548
|
+
["table_name", "name"],
|
|
18549
|
+
["view_definition", "text"]
|
|
18550
|
+
],
|
|
18551
|
+
rows,
|
|
18552
|
+
"views"
|
|
18553
|
+
);
|
|
18554
|
+
}
|
|
18555
|
+
function infoSequences(ctx) {
|
|
18556
|
+
const rows = [];
|
|
18557
|
+
for (const s of allSequences(ctx.state)) {
|
|
18558
|
+
rows.push([
|
|
18559
|
+
CATALOG_NAME,
|
|
18560
|
+
s.schema,
|
|
18561
|
+
s.name,
|
|
18562
|
+
typeDisplayName(s.dataType),
|
|
18563
|
+
String(s.startValue),
|
|
18564
|
+
String(s.minValue),
|
|
18565
|
+
String(s.maxValue),
|
|
18566
|
+
String(s.increment),
|
|
18567
|
+
s.cycle ? "YES" : "NO"
|
|
18568
|
+
]);
|
|
18569
|
+
}
|
|
18570
|
+
return rel(
|
|
18571
|
+
[
|
|
18572
|
+
["sequence_catalog", "name"],
|
|
18573
|
+
["sequence_schema", "name"],
|
|
18574
|
+
["sequence_name", "name"],
|
|
18575
|
+
["data_type", "text"],
|
|
18576
|
+
["start_value", "text"],
|
|
18577
|
+
["minimum_value", "text"],
|
|
18578
|
+
["maximum_value", "text"],
|
|
18579
|
+
["increment", "text"],
|
|
18580
|
+
["cycle_option", "text"]
|
|
18581
|
+
],
|
|
18582
|
+
rows,
|
|
18583
|
+
"sequences"
|
|
18584
|
+
);
|
|
18585
|
+
}
|
|
18586
|
+
function infoTableConstraints(ctx) {
|
|
18587
|
+
const rows = [];
|
|
18588
|
+
for (const t of allTables(ctx.state)) {
|
|
18589
|
+
for (const c of t.constraints) {
|
|
18590
|
+
const type = c.kind === "primary_key" ? "PRIMARY KEY" : c.kind === "unique" ? "UNIQUE" : c.kind === "check" ? "CHECK" : "FOREIGN KEY";
|
|
18591
|
+
rows.push([CATALOG_NAME, t.schema, c.name, CATALOG_NAME, t.schema, t.name, type]);
|
|
18592
|
+
}
|
|
18593
|
+
}
|
|
18594
|
+
return rel(
|
|
18595
|
+
[
|
|
18596
|
+
["constraint_catalog", "name"],
|
|
18597
|
+
["constraint_schema", "name"],
|
|
18598
|
+
["constraint_name", "name"],
|
|
18599
|
+
["table_catalog", "name"],
|
|
18600
|
+
["table_schema", "name"],
|
|
18601
|
+
["table_name", "name"],
|
|
18602
|
+
["constraint_type", "text"]
|
|
18603
|
+
],
|
|
18604
|
+
rows,
|
|
18605
|
+
"table_constraints"
|
|
18606
|
+
);
|
|
18607
|
+
}
|
|
18608
|
+
function infoKeyColumnUsage(ctx) {
|
|
18609
|
+
const rows = [];
|
|
18610
|
+
for (const t of allTables(ctx.state)) {
|
|
18611
|
+
for (const c of t.constraints) {
|
|
18612
|
+
if (c.kind !== "primary_key" && c.kind !== "unique" && c.kind !== "foreign_key") continue;
|
|
18613
|
+
c.columns.forEach((col, i) => {
|
|
18614
|
+
rows.push([CATALOG_NAME, t.schema, c.name, CATALOG_NAME, t.schema, t.name, col, i + 1]);
|
|
18615
|
+
});
|
|
18616
|
+
}
|
|
18617
|
+
}
|
|
18618
|
+
return rel(
|
|
18619
|
+
[
|
|
18620
|
+
["constraint_catalog", "name"],
|
|
18621
|
+
["constraint_schema", "name"],
|
|
18622
|
+
["constraint_name", "name"],
|
|
18623
|
+
["table_catalog", "name"],
|
|
18624
|
+
["table_schema", "name"],
|
|
18625
|
+
["table_name", "name"],
|
|
18626
|
+
["column_name", "name"],
|
|
18627
|
+
["ordinal_position", "int4"]
|
|
18628
|
+
],
|
|
18629
|
+
rows,
|
|
18630
|
+
"key_column_usage"
|
|
18631
|
+
);
|
|
18632
|
+
}
|
|
18633
|
+
function infoRoutines(ctx) {
|
|
18634
|
+
const rows = [];
|
|
18635
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
18636
|
+
for (const fns of schema.functions.values()) {
|
|
18637
|
+
for (const f of fns) {
|
|
18638
|
+
rows.push([
|
|
18639
|
+
CATALOG_NAME,
|
|
18640
|
+
f.schema,
|
|
18641
|
+
f.name,
|
|
18642
|
+
"FUNCTION",
|
|
18643
|
+
f.returns ? typeDisplayName(f.returns) : null,
|
|
18644
|
+
f.language.toUpperCase()
|
|
18645
|
+
]);
|
|
18646
|
+
}
|
|
18647
|
+
}
|
|
18648
|
+
}
|
|
18649
|
+
return rel(
|
|
18650
|
+
[
|
|
18651
|
+
["routine_catalog", "name"],
|
|
18652
|
+
["routine_schema", "name"],
|
|
18653
|
+
["routine_name", "name"],
|
|
18654
|
+
["routine_type", "text"],
|
|
18655
|
+
["data_type", "text"],
|
|
18656
|
+
["external_language", "text"]
|
|
18657
|
+
],
|
|
18658
|
+
rows,
|
|
18659
|
+
"routines"
|
|
18660
|
+
);
|
|
18661
|
+
}
|
|
18662
|
+
function buildCatalogRelation(ctx, schema, name) {
|
|
18663
|
+
if (schema === "pg_catalog") {
|
|
18664
|
+
switch (name) {
|
|
18665
|
+
case "pg_namespace":
|
|
18666
|
+
return pgNamespace(ctx.state);
|
|
18667
|
+
case "pg_class":
|
|
18668
|
+
return pgClass(ctx);
|
|
18669
|
+
case "pg_attribute":
|
|
18670
|
+
return pgAttribute(ctx);
|
|
18671
|
+
case "pg_type":
|
|
18672
|
+
return pgType(ctx);
|
|
18673
|
+
case "pg_proc":
|
|
18674
|
+
return pgProc(ctx);
|
|
18675
|
+
case "pg_enum":
|
|
18676
|
+
return pgEnum(ctx);
|
|
18677
|
+
case "pg_constraint":
|
|
18678
|
+
return pgConstraint(ctx);
|
|
18679
|
+
case "pg_index":
|
|
18680
|
+
return pgIndex(ctx);
|
|
18681
|
+
case "pg_sequence":
|
|
18682
|
+
return pgSequence(ctx);
|
|
18683
|
+
case "pg_sequences":
|
|
18684
|
+
return pgSequencesView(ctx);
|
|
18685
|
+
case "pg_tables":
|
|
18686
|
+
return pgTables(ctx);
|
|
18687
|
+
case "pg_views":
|
|
18688
|
+
return pgViews(ctx, false);
|
|
18689
|
+
case "pg_matviews":
|
|
18690
|
+
return pgViews(ctx, true);
|
|
18691
|
+
case "pg_indexes":
|
|
18692
|
+
return pgIndexesView(ctx);
|
|
18693
|
+
case "pg_settings":
|
|
18694
|
+
return pgSettings(ctx);
|
|
18695
|
+
case "pg_database":
|
|
18696
|
+
return pgDatabase();
|
|
18697
|
+
case "pg_roles":
|
|
18698
|
+
case "pg_user":
|
|
18699
|
+
return pgRoles();
|
|
18700
|
+
case "pg_trigger":
|
|
18701
|
+
return pgTrigger(ctx);
|
|
18702
|
+
default:
|
|
18703
|
+
return null;
|
|
18704
|
+
}
|
|
18705
|
+
}
|
|
18706
|
+
switch (name) {
|
|
18707
|
+
case "schemata":
|
|
18708
|
+
return infoSchemata(ctx.state);
|
|
18709
|
+
case "tables":
|
|
18710
|
+
return infoTables(ctx);
|
|
18711
|
+
case "columns":
|
|
18712
|
+
return infoColumns(ctx);
|
|
18713
|
+
case "views":
|
|
18714
|
+
return infoViews(ctx);
|
|
18715
|
+
case "sequences":
|
|
18716
|
+
return infoSequences(ctx);
|
|
18717
|
+
case "table_constraints":
|
|
18718
|
+
return infoTableConstraints(ctx);
|
|
18719
|
+
case "key_column_usage":
|
|
18720
|
+
return infoKeyColumnUsage(ctx);
|
|
18721
|
+
case "routines":
|
|
18722
|
+
return infoRoutines(ctx);
|
|
18723
|
+
default:
|
|
18724
|
+
return null;
|
|
18725
|
+
}
|
|
18726
|
+
}
|
|
18727
|
+
setCatalogBuilder(buildCatalogRelation);
|
|
18728
|
+
|
|
18729
|
+
// src/executor/triggers-exec.ts
|
|
18730
|
+
var PlParser = class {
|
|
18731
|
+
constructor(src) {
|
|
18732
|
+
this.src = src;
|
|
18733
|
+
this.tokens = tokenize(src);
|
|
18734
|
+
}
|
|
18735
|
+
src;
|
|
18736
|
+
tokens;
|
|
18737
|
+
pos = 0;
|
|
18738
|
+
peek(offset = 0) {
|
|
18739
|
+
return this.tokens[Math.min(this.pos + offset, this.tokens.length - 1)];
|
|
18740
|
+
}
|
|
18741
|
+
next() {
|
|
18742
|
+
const t = this.peek();
|
|
18743
|
+
if (t.type !== "eof") this.pos++;
|
|
18744
|
+
return t;
|
|
18745
|
+
}
|
|
18746
|
+
atKw(kw) {
|
|
18747
|
+
const t = this.peek();
|
|
18748
|
+
return t.type === "ident" && t.value === kw;
|
|
18749
|
+
}
|
|
18750
|
+
expectKw(kw) {
|
|
18751
|
+
if (!this.atKw(kw)) throw unsupported(`trigger body: expected "${kw.toUpperCase()}" near "${this.peek().value}"`);
|
|
18752
|
+
this.pos++;
|
|
18753
|
+
}
|
|
18754
|
+
expectSemi() {
|
|
18755
|
+
const t = this.next();
|
|
18756
|
+
if (t.type !== "punct" || t.value !== ";") throw unsupported(`trigger body: expected ";" near "${t.value}"`);
|
|
18757
|
+
}
|
|
18758
|
+
parseBody() {
|
|
18759
|
+
if (this.atKw("declare")) throw unsupported("trigger body: DECLARE section");
|
|
18760
|
+
this.expectKw("begin");
|
|
18761
|
+
const stmts = this.parseStmts();
|
|
18762
|
+
this.expectKw("end");
|
|
18763
|
+
if (this.peek().type === "punct" && this.peek().value === ";") this.pos++;
|
|
18764
|
+
if (this.peek().type !== "eof") throw unsupported(`trigger body: trailing content near "${this.peek().value}"`);
|
|
18765
|
+
return stmts;
|
|
18766
|
+
}
|
|
18767
|
+
parseStmts() {
|
|
18768
|
+
const out = [];
|
|
18769
|
+
while (!this.atKw("end") && !this.atKw("elsif") && !this.atKw("else") && this.peek().type !== "eof") {
|
|
18770
|
+
out.push(this.parseStmt());
|
|
18771
|
+
}
|
|
18772
|
+
return out;
|
|
18773
|
+
}
|
|
18774
|
+
parseStmt() {
|
|
18775
|
+
if (this.atKw("return")) {
|
|
18776
|
+
this.pos++;
|
|
18777
|
+
const t = this.next();
|
|
18778
|
+
let what;
|
|
18779
|
+
if (t.type === "ident" && (t.value === "new" || t.value === "old" || t.value === "null")) {
|
|
18780
|
+
what = t.value;
|
|
18781
|
+
} else {
|
|
18782
|
+
throw unsupported(`trigger body: RETURN ${t.value}`);
|
|
18783
|
+
}
|
|
18784
|
+
this.expectSemi();
|
|
18785
|
+
return { kind: "return", what };
|
|
18786
|
+
}
|
|
18787
|
+
if (this.atKw("if")) {
|
|
18788
|
+
this.pos++;
|
|
18789
|
+
const branches = [];
|
|
18790
|
+
let elseBody = [];
|
|
18791
|
+
const cond = this.parseExprUntilKw("then");
|
|
18792
|
+
branches.push({ cond, body: this.parseStmts() });
|
|
18793
|
+
while (this.atKw("elsif")) {
|
|
18794
|
+
this.pos++;
|
|
18795
|
+
const c = this.parseExprUntilKw("then");
|
|
18796
|
+
branches.push({ cond: c, body: this.parseStmts() });
|
|
18797
|
+
}
|
|
18798
|
+
if (this.atKw("else")) {
|
|
18799
|
+
this.pos++;
|
|
18800
|
+
elseBody = this.parseStmts();
|
|
18801
|
+
}
|
|
18802
|
+
this.expectKw("end");
|
|
18803
|
+
this.expectKw("if");
|
|
18804
|
+
this.expectSemi();
|
|
18805
|
+
return { kind: "if", branches, elseBody };
|
|
18806
|
+
}
|
|
18807
|
+
if (this.atKw("null")) {
|
|
18808
|
+
this.pos++;
|
|
18809
|
+
this.expectSemi();
|
|
18810
|
+
return { kind: "null" };
|
|
18811
|
+
}
|
|
18812
|
+
if (this.atKw("raise")) {
|
|
18813
|
+
this.pos++;
|
|
18814
|
+
if (this.peek().type === "ident") this.pos++;
|
|
18815
|
+
let message = "";
|
|
18816
|
+
while (!(this.peek().type === "punct" && this.peek().value === ";") && this.peek().type !== "eof") {
|
|
18817
|
+
const t = this.next();
|
|
18818
|
+
if (t.type === "string" && message === "") message = t.value;
|
|
18819
|
+
}
|
|
18820
|
+
this.expectSemi();
|
|
18821
|
+
return { kind: "raise", message: message || "raised exception" };
|
|
18822
|
+
}
|
|
18823
|
+
const target = [];
|
|
18824
|
+
const first = this.next();
|
|
18825
|
+
if (first.type !== "ident" && first.type !== "quoted_ident") {
|
|
18826
|
+
throw unsupported(`trigger body statement near "${first.value}"`);
|
|
18827
|
+
}
|
|
18828
|
+
target.push(first.type === "ident" ? first.value : first.value);
|
|
18829
|
+
while (this.peek().type === "punct" && this.peek().value === ".") {
|
|
18830
|
+
this.pos++;
|
|
18831
|
+
const f = this.next();
|
|
18832
|
+
target.push(f.value);
|
|
18833
|
+
}
|
|
18834
|
+
const opTok = this.next();
|
|
18835
|
+
if (!(opTok.type === "op" && (opTok.value === ":=" || opTok.value === "="))) {
|
|
18836
|
+
throw unsupported(`trigger body: expected assignment near "${opTok.value}"`);
|
|
18837
|
+
}
|
|
18838
|
+
const expr = this.parseExprUntilSemi();
|
|
18839
|
+
return { kind: "assign", target, expr };
|
|
18840
|
+
}
|
|
18841
|
+
/** Slice raw source from the current token to the terminator and parse as a SQL expression. */
|
|
18842
|
+
parseExprUntilSemi() {
|
|
18843
|
+
const start = this.peek().pos;
|
|
18844
|
+
let depth = 0;
|
|
18845
|
+
for (; ; ) {
|
|
18846
|
+
const t = this.peek();
|
|
18847
|
+
if (t.type === "eof") throw unsupported("trigger body: unterminated statement");
|
|
18848
|
+
if (t.type === "punct" && t.value === "(") depth++;
|
|
18849
|
+
if (t.type === "punct" && t.value === ")") depth--;
|
|
18850
|
+
if (t.type === "punct" && t.value === ";" && depth === 0) {
|
|
18851
|
+
const text = this.src.slice(start, t.pos);
|
|
18852
|
+
this.pos++;
|
|
18853
|
+
return parseSqlExpr(text);
|
|
18854
|
+
}
|
|
18855
|
+
this.pos++;
|
|
18856
|
+
}
|
|
18857
|
+
}
|
|
18858
|
+
parseExprUntilKw(kw) {
|
|
18859
|
+
const start = this.peek().pos;
|
|
18860
|
+
let depth = 0;
|
|
18861
|
+
for (; ; ) {
|
|
18862
|
+
const t = this.peek();
|
|
18863
|
+
if (t.type === "eof") throw unsupported(`trigger body: expected "${kw.toUpperCase()}"`);
|
|
18864
|
+
if (t.type === "punct" && t.value === "(") depth++;
|
|
18865
|
+
if (t.type === "punct" && t.value === ")") depth--;
|
|
18866
|
+
if (t.type === "ident" && t.value === kw && depth === 0) {
|
|
18867
|
+
const text = this.src.slice(start, t.pos);
|
|
18868
|
+
this.pos++;
|
|
18869
|
+
return parseSqlExpr(text);
|
|
18870
|
+
}
|
|
18871
|
+
this.pos++;
|
|
18872
|
+
}
|
|
18873
|
+
}
|
|
18874
|
+
};
|
|
18875
|
+
function parseSqlExpr(text) {
|
|
18876
|
+
const stmts = parse(`SELECT ${text}`);
|
|
18877
|
+
const sel = stmts[0];
|
|
18878
|
+
const body = sel.body;
|
|
18879
|
+
const target = body.targets?.[0];
|
|
18880
|
+
if (!target) throw unsupported(`trigger body expression "${text}"`);
|
|
18881
|
+
return target.expr;
|
|
18882
|
+
}
|
|
18883
|
+
var bodyCache = /* @__PURE__ */ new Map();
|
|
18884
|
+
function compiledBody(fn) {
|
|
18885
|
+
const raw = fn.rawBody;
|
|
18886
|
+
if (raw === null) throw unsupported(`trigger function ${fn.name} has no body`);
|
|
18887
|
+
let cached = bodyCache.get(raw);
|
|
18888
|
+
if (cached === void 0) {
|
|
18889
|
+
cached = new PlParser(raw).parseBody();
|
|
18890
|
+
bodyCache.set(raw, cached);
|
|
18891
|
+
}
|
|
18892
|
+
return cached;
|
|
18893
|
+
}
|
|
18894
|
+
var ReturnSignal = class {
|
|
18895
|
+
constructor(row) {
|
|
18896
|
+
this.row = row;
|
|
18897
|
+
}
|
|
18898
|
+
row;
|
|
18899
|
+
};
|
|
18900
|
+
function runTriggerBody(env, table, stmts, vars) {
|
|
18901
|
+
const scope = () => triggerScope(table, vars.newRow, vars.oldRow);
|
|
18902
|
+
for (const stmt of stmts) {
|
|
18903
|
+
switch (stmt.kind) {
|
|
18904
|
+
case "assign": {
|
|
18905
|
+
if (stmt.target.length !== 2 || stmt.target[0] !== "new") {
|
|
18906
|
+
throw unsupported(`trigger body: assignment to "${stmt.target.join(".")}"`);
|
|
18907
|
+
}
|
|
18908
|
+
if (vars.newRow === null) {
|
|
18909
|
+
throw pgError("object_not_in_prerequisite_state", `record "new" is not assigned yet`, "55000");
|
|
18910
|
+
}
|
|
18911
|
+
const colName = stmt.target[1];
|
|
18912
|
+
const idx = table.columns.findIndex((c) => c.name === colName);
|
|
18913
|
+
if (idx === -1) {
|
|
18914
|
+
throw pgError("undefined_column", `record "new" has no field "${colName}"`, "42703");
|
|
18915
|
+
}
|
|
18916
|
+
const v = evalScalar(env, scope(), stmt.expr);
|
|
18917
|
+
vars.newRow = vars.newRow.slice();
|
|
18918
|
+
vars.newRow[idx] = v.v === null ? null : castTo(env.ctx, v, table.columns[idx].type.id, { assignment: true }).v;
|
|
18919
|
+
break;
|
|
18920
|
+
}
|
|
18921
|
+
case "return":
|
|
18922
|
+
throw new ReturnSignal(stmt.what === "new" ? vars.newRow : stmt.what === "old" ? vars.oldRow : null);
|
|
18923
|
+
case "if": {
|
|
18924
|
+
let taken = false;
|
|
18925
|
+
for (const b of stmt.branches) {
|
|
18926
|
+
if (evalPredicate(env, scope(), b.cond)) {
|
|
18927
|
+
runTriggerBody(env, table, b.body, vars);
|
|
18928
|
+
taken = true;
|
|
18929
|
+
break;
|
|
18930
|
+
}
|
|
18931
|
+
}
|
|
18932
|
+
if (!taken) runTriggerBody(env, table, stmt.elseBody, vars);
|
|
18933
|
+
break;
|
|
18934
|
+
}
|
|
18935
|
+
case "null":
|
|
18936
|
+
break;
|
|
18937
|
+
case "raise":
|
|
18938
|
+
throw pgError("raise_exception", stmt.message, "P0001");
|
|
18939
|
+
}
|
|
18940
|
+
}
|
|
18941
|
+
}
|
|
18942
|
+
function triggerScope(table, newRow, oldRow) {
|
|
18943
|
+
const cols = [];
|
|
18944
|
+
const row = [];
|
|
18945
|
+
const rangeVars = /* @__PURE__ */ new Set();
|
|
18946
|
+
if (newRow) {
|
|
18947
|
+
rangeVars.add("new");
|
|
18948
|
+
for (let i = 0; i < table.columns.length; i++) {
|
|
18949
|
+
cols.push({ name: table.columns[i].name, type: table.columns[i].type.id, table: "new" });
|
|
18950
|
+
row.push(newRow[i] ?? null);
|
|
18951
|
+
}
|
|
18952
|
+
}
|
|
18953
|
+
if (oldRow) {
|
|
18954
|
+
rangeVars.add("old");
|
|
18955
|
+
for (let i = 0; i < table.columns.length; i++) {
|
|
18956
|
+
cols.push({ name: table.columns[i].name, type: table.columns[i].type.id, table: "old" });
|
|
18957
|
+
row.push(oldRow[i] ?? null);
|
|
18958
|
+
}
|
|
18959
|
+
}
|
|
18960
|
+
return new RowScope(cols, row, null, rangeVars);
|
|
18961
|
+
}
|
|
18962
|
+
function executeTrigger(env, table, trigger, _event, oldRow, newRow) {
|
|
18963
|
+
const state = env.ctx.state;
|
|
18964
|
+
if (trigger.when !== null && !evalPredicate(env, triggerScope(table, newRow, oldRow), trigger.when)) {
|
|
18965
|
+
return newRow;
|
|
18966
|
+
}
|
|
18967
|
+
const fns = state.schemas.get(trigger.funcSchema)?.functions.get(trigger.funcName);
|
|
18968
|
+
const fn = fns?.[0];
|
|
18969
|
+
if (!fn) {
|
|
18970
|
+
throw pgError("undefined_function", `function ${trigger.funcSchema}.${trigger.funcName}() does not exist`, "42883");
|
|
18971
|
+
}
|
|
18972
|
+
const stmts = compiledBody(fn);
|
|
18973
|
+
const vars = { newRow: newRow ? newRow.slice() : null, oldRow };
|
|
18974
|
+
try {
|
|
18975
|
+
runTriggerBody(env, table, stmts, vars);
|
|
18976
|
+
} catch (e) {
|
|
18977
|
+
if (e instanceof ReturnSignal) return e.row;
|
|
18978
|
+
throw e;
|
|
18979
|
+
}
|
|
18980
|
+
throw pgError("invalid_function_definition", `control reached end of trigger procedure without RETURN`, "2F005");
|
|
18981
|
+
}
|
|
18982
|
+
setTriggerExecutor(executeTrigger);
|
|
18983
|
+
|
|
17854
18984
|
// src/executor/ddl.ts
|
|
17855
18985
|
function targetSchema(env, parts) {
|
|
17856
18986
|
const state = env.ctx.state;
|
|
@@ -18215,8 +19345,8 @@ function executeCreateTableAs(env, stmt) {
|
|
|
18215
19345
|
if (stmt.ifNotExists) return commandResult("CREATE TABLE AS", 0);
|
|
18216
19346
|
throw pgError("duplicate_table", `relation "${name}" already exists`, "42P07");
|
|
18217
19347
|
}
|
|
18218
|
-
const
|
|
18219
|
-
const columns =
|
|
19348
|
+
const rel2 = executeSelectStmt(env, stmt.query);
|
|
19349
|
+
const columns = rel2.columns.map((c, i) => ({
|
|
18220
19350
|
name: stmt.columns?.[i] ?? c.name,
|
|
18221
19351
|
type: { id: c.type === UNKNOWN ? "text" : c.type, mod: null },
|
|
18222
19352
|
notNull: false,
|
|
@@ -18228,7 +19358,7 @@ function executeCreateTableAs(env, stmt) {
|
|
|
18228
19358
|
}));
|
|
18229
19359
|
const table = new TableData(schema.name, name, columns, state.nextOid(), stmt.temp);
|
|
18230
19360
|
if (stmt.withData) {
|
|
18231
|
-
table.rows =
|
|
19361
|
+
table.rows = rel2.rows.map((r) => r.slice());
|
|
18232
19362
|
}
|
|
18233
19363
|
schema.tables.set(name, table);
|
|
18234
19364
|
const count = stmt.withData ? table.rows.length : 0;
|
|
@@ -18299,12 +19429,12 @@ function executeCreateView(env, stmt) {
|
|
|
18299
19429
|
let matRows = null;
|
|
18300
19430
|
let matColumns = null;
|
|
18301
19431
|
if (stmt.materialized) {
|
|
18302
|
-
const
|
|
18303
|
-
matColumns =
|
|
19432
|
+
const rel2 = executeSelectStmt({ ctx: env.ctx, params: null, ctes: /* @__PURE__ */ new Map(), outer: null }, stmt.query);
|
|
19433
|
+
matColumns = rel2.columns.map((c, i) => ({
|
|
18304
19434
|
name: stmt.columns?.[i] ?? c.name,
|
|
18305
19435
|
type: c.type === UNKNOWN ? "text" : c.type
|
|
18306
19436
|
}));
|
|
18307
|
-
matRows = stmt.withData ?
|
|
19437
|
+
matRows = stmt.withData ? rel2.rows : null;
|
|
18308
19438
|
}
|
|
18309
19439
|
schema.views.set(name, {
|
|
18310
19440
|
name,
|
|
@@ -18324,12 +19454,12 @@ function executeRefreshMatView(env, stmt) {
|
|
|
18324
19454
|
if (!view?.materialized) {
|
|
18325
19455
|
throw pgError("undefined_table", `materialized view "${stmt.name.join(".")}" does not exist`, "42P01");
|
|
18326
19456
|
}
|
|
18327
|
-
const
|
|
18328
|
-
view.matColumns =
|
|
19457
|
+
const rel2 = executeSelectStmt({ ctx: env.ctx, params: null, ctes: /* @__PURE__ */ new Map(), outer: null }, view.query);
|
|
19458
|
+
view.matColumns = rel2.columns.map((c, i) => ({
|
|
18329
19459
|
name: view.columns?.[i] ?? c.name,
|
|
18330
19460
|
type: c.type === UNKNOWN ? "text" : c.type
|
|
18331
19461
|
}));
|
|
18332
|
-
view.matRows = stmt.withData ?
|
|
19462
|
+
view.matRows = stmt.withData ? rel2.rows : null;
|
|
18333
19463
|
return commandResult("REFRESH MATERIALIZED VIEW", 0);
|
|
18334
19464
|
}
|
|
18335
19465
|
function executeCreateSchema(env, stmt) {
|
|
@@ -19494,8 +20624,8 @@ var Database = class {
|
|
|
19494
20624
|
*/
|
|
19495
20625
|
snapshot() {
|
|
19496
20626
|
this.assertOpen();
|
|
19497
|
-
const { encodeDatabaseState } = requireCodec();
|
|
19498
|
-
return
|
|
20627
|
+
const { encodeDatabaseState: encodeDatabaseState2 } = requireCodec();
|
|
20628
|
+
return encodeDatabaseState2(this.state, {
|
|
19499
20629
|
prngState: this.prng.getState(),
|
|
19500
20630
|
nowMs: this.now().getTime()
|
|
19501
20631
|
});
|
|
@@ -19506,8 +20636,8 @@ var Database = class {
|
|
|
19506
20636
|
if (this.transactions.inTransaction) {
|
|
19507
20637
|
throw pgError("transaction_state", "cannot restore during a transaction", "25P01");
|
|
19508
20638
|
}
|
|
19509
|
-
const { decodeDatabaseState } = requireCodec();
|
|
19510
|
-
const decoded =
|
|
20639
|
+
const { decodeDatabaseState: decodeDatabaseState2 } = requireCodec();
|
|
20640
|
+
const decoded = decodeDatabaseState2(snapshot, this.prng, () => this.now());
|
|
19511
20641
|
this.state.restoreFrom(decoded.state);
|
|
19512
20642
|
if (decoded.runtime) {
|
|
19513
20643
|
this.prng.setState(decoded.runtime.prngState);
|
|
@@ -19567,6 +20697,9 @@ var Database = class {
|
|
|
19567
20697
|
}
|
|
19568
20698
|
};
|
|
19569
20699
|
var codec = null;
|
|
20700
|
+
function registerCodec(m) {
|
|
20701
|
+
codec = m;
|
|
20702
|
+
}
|
|
19570
20703
|
function requireCodec() {
|
|
19571
20704
|
if (!codec) {
|
|
19572
20705
|
throw new PostgresError("unsupported", "snapshot codec not loaded");
|
|
@@ -19583,6 +20716,483 @@ if (typeof disposeKey === "symbol") {
|
|
|
19583
20716
|
configurable: true
|
|
19584
20717
|
});
|
|
19585
20718
|
}
|
|
20719
|
+
|
|
20720
|
+
// src/serialization/codec.ts
|
|
20721
|
+
var TEXT_ENCODER = new TextEncoder();
|
|
20722
|
+
var TEXT_DECODER = new TextDecoder();
|
|
20723
|
+
var utf8Encode = (s) => TEXT_ENCODER.encode(s);
|
|
20724
|
+
var utf8Decode = (b) => TEXT_DECODER.decode(b);
|
|
20725
|
+
var MAGIC = utf8Encode("PGMM");
|
|
20726
|
+
var VERSION = 1;
|
|
20727
|
+
var Writer = class {
|
|
20728
|
+
buf = new Uint8Array(1024);
|
|
20729
|
+
len = 0;
|
|
20730
|
+
ensure(needed) {
|
|
20731
|
+
if (this.len + needed <= this.buf.length) return;
|
|
20732
|
+
let cap = this.buf.length;
|
|
20733
|
+
while (cap < this.len + needed) cap *= 2;
|
|
20734
|
+
const next = new Uint8Array(cap);
|
|
20735
|
+
next.set(this.buf.subarray(0, this.len));
|
|
20736
|
+
this.buf = next;
|
|
20737
|
+
}
|
|
20738
|
+
u8(value) {
|
|
20739
|
+
this.ensure(1);
|
|
20740
|
+
this.buf[this.len++] = value & 255;
|
|
20741
|
+
}
|
|
20742
|
+
u32(value) {
|
|
20743
|
+
this.ensure(4);
|
|
20744
|
+
this.buf[this.len++] = value & 255;
|
|
20745
|
+
this.buf[this.len++] = value >>> 8 & 255;
|
|
20746
|
+
this.buf[this.len++] = value >>> 16 & 255;
|
|
20747
|
+
this.buf[this.len++] = value >>> 24 & 255;
|
|
20748
|
+
}
|
|
20749
|
+
i32(value) {
|
|
20750
|
+
this.u32(value | 0);
|
|
20751
|
+
}
|
|
20752
|
+
u64(value) {
|
|
20753
|
+
const bytes = new Uint8Array(8);
|
|
20754
|
+
new DataView(bytes.buffer).setBigUint64(0, BigInt.asUintN(64, value), true);
|
|
20755
|
+
this.raw(bytes);
|
|
20756
|
+
}
|
|
20757
|
+
i64(value) {
|
|
20758
|
+
const bytes = new Uint8Array(8);
|
|
20759
|
+
new DataView(bytes.buffer).setBigInt64(0, value, true);
|
|
20760
|
+
this.raw(bytes);
|
|
20761
|
+
}
|
|
20762
|
+
f64(value) {
|
|
20763
|
+
const bytes = new Uint8Array(8);
|
|
20764
|
+
new DataView(bytes.buffer).setFloat64(0, value, true);
|
|
20765
|
+
this.raw(bytes);
|
|
20766
|
+
}
|
|
20767
|
+
raw(value) {
|
|
20768
|
+
this.ensure(value.length);
|
|
20769
|
+
this.buf.set(value, this.len);
|
|
20770
|
+
this.len += value.length;
|
|
20771
|
+
}
|
|
20772
|
+
text(value) {
|
|
20773
|
+
const bytes = utf8Encode(value);
|
|
20774
|
+
this.u32(bytes.length);
|
|
20775
|
+
this.raw(bytes);
|
|
20776
|
+
}
|
|
20777
|
+
json(value) {
|
|
20778
|
+
this.text(JSON.stringify(value, jsonReplacer) ?? "null");
|
|
20779
|
+
}
|
|
20780
|
+
datum(value) {
|
|
20781
|
+
if (value === null) {
|
|
20782
|
+
this.u8(0);
|
|
20783
|
+
return;
|
|
20784
|
+
}
|
|
20785
|
+
if (typeof value === "boolean") {
|
|
20786
|
+
this.u8(1);
|
|
20787
|
+
this.u8(value ? 1 : 0);
|
|
20788
|
+
return;
|
|
20789
|
+
}
|
|
20790
|
+
if (typeof value === "number") {
|
|
20791
|
+
this.u8(2);
|
|
20792
|
+
this.f64(value);
|
|
20793
|
+
return;
|
|
20794
|
+
}
|
|
20795
|
+
if (typeof value === "bigint") {
|
|
20796
|
+
this.u8(3);
|
|
20797
|
+
this.i64(value);
|
|
20798
|
+
return;
|
|
20799
|
+
}
|
|
20800
|
+
if (typeof value === "string") {
|
|
20801
|
+
this.u8(4);
|
|
20802
|
+
this.text(value);
|
|
20803
|
+
return;
|
|
20804
|
+
}
|
|
20805
|
+
if (value instanceof Uint8Array) {
|
|
20806
|
+
this.u8(5);
|
|
20807
|
+
this.u32(value.length);
|
|
20808
|
+
this.raw(value);
|
|
20809
|
+
return;
|
|
20810
|
+
}
|
|
20811
|
+
switch (value.kind) {
|
|
20812
|
+
case "numeric": {
|
|
20813
|
+
this.u8(6);
|
|
20814
|
+
this.text(value.coef.toString());
|
|
20815
|
+
this.u32(value.dscale);
|
|
20816
|
+
this.u8(value.special === null ? 0 : value.special === "nan" ? 1 : value.special === "inf" ? 2 : 3);
|
|
20817
|
+
return;
|
|
20818
|
+
}
|
|
20819
|
+
case "interval": {
|
|
20820
|
+
this.u8(7);
|
|
20821
|
+
this.i32(value.months);
|
|
20822
|
+
this.i32(value.days);
|
|
20823
|
+
this.i64(value.micros);
|
|
20824
|
+
return;
|
|
20825
|
+
}
|
|
20826
|
+
case "pgarray": {
|
|
20827
|
+
this.u8(8);
|
|
20828
|
+
this.text(value.elem);
|
|
20829
|
+
this.u32(value.dims.length);
|
|
20830
|
+
for (const d of value.dims) this.i32(d);
|
|
20831
|
+
for (const l of value.lbs) this.i32(l);
|
|
20832
|
+
this.u32(value.items.length);
|
|
20833
|
+
for (const item of value.items) this.datum(item);
|
|
20834
|
+
return;
|
|
20835
|
+
}
|
|
20836
|
+
case "pgrecord": {
|
|
20837
|
+
this.u8(9);
|
|
20838
|
+
this.json(value.types);
|
|
20839
|
+
this.json(value.names ?? null);
|
|
20840
|
+
this.u32(value.values.length);
|
|
20841
|
+
for (const item of value.values) this.datum(item);
|
|
20842
|
+
return;
|
|
20843
|
+
}
|
|
20844
|
+
case "jsonb": {
|
|
20845
|
+
this.u8(10);
|
|
20846
|
+
this.text(jsonbText(value.value));
|
|
20847
|
+
return;
|
|
20848
|
+
}
|
|
20849
|
+
default: {
|
|
20850
|
+
const tz = value;
|
|
20851
|
+
if (typeof tz.micros === "bigint" && typeof tz.offsetSec === "number") {
|
|
20852
|
+
this.u8(11);
|
|
20853
|
+
this.i64(tz.micros);
|
|
20854
|
+
this.i32(tz.offsetSec);
|
|
20855
|
+
return;
|
|
20856
|
+
}
|
|
20857
|
+
throw snapshotError();
|
|
20858
|
+
}
|
|
20859
|
+
}
|
|
20860
|
+
}
|
|
20861
|
+
finish() {
|
|
20862
|
+
if (this.len === this.buf.length) return this.buf;
|
|
20863
|
+
return this.buf.slice(0, this.len);
|
|
20864
|
+
}
|
|
20865
|
+
};
|
|
20866
|
+
var Reader = class {
|
|
20867
|
+
constructor(bytes) {
|
|
20868
|
+
this.bytes = bytes;
|
|
20869
|
+
}
|
|
20870
|
+
bytes;
|
|
20871
|
+
offset = 0;
|
|
20872
|
+
u8() {
|
|
20873
|
+
if (this.offset >= this.bytes.length) this.fail();
|
|
20874
|
+
return this.bytes[this.offset++];
|
|
20875
|
+
}
|
|
20876
|
+
u32() {
|
|
20877
|
+
if (this.offset + 4 > this.bytes.length) this.fail();
|
|
20878
|
+
const value = new DataView(this.bytes.buffer, this.bytes.byteOffset + this.offset, 4).getUint32(0, true);
|
|
20879
|
+
this.offset += 4;
|
|
20880
|
+
return value;
|
|
20881
|
+
}
|
|
20882
|
+
i32() {
|
|
20883
|
+
return this.u32() | 0;
|
|
20884
|
+
}
|
|
20885
|
+
u64() {
|
|
20886
|
+
const bytes = this.raw(8);
|
|
20887
|
+
return new DataView(bytes.buffer, bytes.byteOffset, 8).getBigUint64(0, true);
|
|
20888
|
+
}
|
|
20889
|
+
i64() {
|
|
20890
|
+
const bytes = this.raw(8);
|
|
20891
|
+
return new DataView(bytes.buffer, bytes.byteOffset, 8).getBigInt64(0, true);
|
|
20892
|
+
}
|
|
20893
|
+
f64() {
|
|
20894
|
+
const bytes = this.raw(8);
|
|
20895
|
+
return new DataView(bytes.buffer, bytes.byteOffset, 8).getFloat64(0, true);
|
|
20896
|
+
}
|
|
20897
|
+
raw(length) {
|
|
20898
|
+
if (length < 0 || this.offset + length > this.bytes.length) this.fail();
|
|
20899
|
+
const value = this.bytes.slice(this.offset, this.offset + length);
|
|
20900
|
+
this.offset += length;
|
|
20901
|
+
return value;
|
|
20902
|
+
}
|
|
20903
|
+
text() {
|
|
20904
|
+
return utf8Decode(this.raw(this.u32()));
|
|
20905
|
+
}
|
|
20906
|
+
json() {
|
|
20907
|
+
try {
|
|
20908
|
+
return JSON.parse(this.text(), jsonReviver);
|
|
20909
|
+
} catch {
|
|
20910
|
+
throw snapshotError();
|
|
20911
|
+
}
|
|
20912
|
+
}
|
|
20913
|
+
datum() {
|
|
20914
|
+
const tag = this.u8();
|
|
20915
|
+
switch (tag) {
|
|
20916
|
+
case 0:
|
|
20917
|
+
return null;
|
|
20918
|
+
case 1:
|
|
20919
|
+
return this.u8() !== 0;
|
|
20920
|
+
case 2:
|
|
20921
|
+
return this.f64();
|
|
20922
|
+
case 3:
|
|
20923
|
+
return this.i64();
|
|
20924
|
+
case 4:
|
|
20925
|
+
return this.text();
|
|
20926
|
+
case 5:
|
|
20927
|
+
return this.raw(this.u32());
|
|
20928
|
+
case 6: {
|
|
20929
|
+
const coef = BigInt(this.text());
|
|
20930
|
+
const dscale = this.u32();
|
|
20931
|
+
const specialTag = this.u8();
|
|
20932
|
+
const special = specialTag === 0 ? null : specialTag === 1 ? "nan" : specialTag === 2 ? "inf" : "-inf";
|
|
20933
|
+
return { kind: "numeric", coef, dscale, special };
|
|
20934
|
+
}
|
|
20935
|
+
case 7: {
|
|
20936
|
+
const months = this.i32();
|
|
20937
|
+
const days = this.i32();
|
|
20938
|
+
const micros = this.i64();
|
|
20939
|
+
return { kind: "interval", months, days, micros };
|
|
20940
|
+
}
|
|
20941
|
+
case 8: {
|
|
20942
|
+
const elem = this.text();
|
|
20943
|
+
const ndims = this.u32();
|
|
20944
|
+
const dims = [];
|
|
20945
|
+
for (let i = 0; i < ndims; i++) dims.push(this.i32());
|
|
20946
|
+
const lbs = [];
|
|
20947
|
+
for (let i = 0; i < ndims; i++) lbs.push(this.i32());
|
|
20948
|
+
const count = this.u32();
|
|
20949
|
+
const items = [];
|
|
20950
|
+
for (let i = 0; i < count; i++) items.push(this.datum());
|
|
20951
|
+
return { kind: "pgarray", elem, dims, lbs, items };
|
|
20952
|
+
}
|
|
20953
|
+
case 9: {
|
|
20954
|
+
const types = this.json();
|
|
20955
|
+
const names = this.json();
|
|
20956
|
+
const count = this.u32();
|
|
20957
|
+
const values = [];
|
|
20958
|
+
for (let i = 0; i < count; i++) values.push(this.datum());
|
|
20959
|
+
const rec = names ? { kind: "pgrecord", types, values, names } : { kind: "pgrecord", types, values };
|
|
20960
|
+
return rec;
|
|
20961
|
+
}
|
|
20962
|
+
case 10:
|
|
20963
|
+
return { kind: "jsonb", value: parseJsonText(this.text()) };
|
|
20964
|
+
case 11: {
|
|
20965
|
+
const micros = this.i64();
|
|
20966
|
+
const offsetSec = this.i32();
|
|
20967
|
+
return { micros, offsetSec };
|
|
20968
|
+
}
|
|
20969
|
+
default:
|
|
20970
|
+
this.fail();
|
|
20971
|
+
}
|
|
20972
|
+
}
|
|
20973
|
+
remaining() {
|
|
20974
|
+
return this.bytes.length - this.offset;
|
|
20975
|
+
}
|
|
20976
|
+
done() {
|
|
20977
|
+
return this.offset === this.bytes.length;
|
|
20978
|
+
}
|
|
20979
|
+
fail() {
|
|
20980
|
+
throw snapshotError();
|
|
20981
|
+
}
|
|
20982
|
+
};
|
|
20983
|
+
function encodeDatabaseState(state, runtime) {
|
|
20984
|
+
const w = new Writer();
|
|
20985
|
+
w.raw(MAGIC);
|
|
20986
|
+
w.u32(VERSION);
|
|
20987
|
+
w.u32(state.oidCounter);
|
|
20988
|
+
w.u32(state.changes);
|
|
20989
|
+
const settings = [...state.settings.entries()].sort((a, b) => compareNames(a[0], b[0]));
|
|
20990
|
+
w.u32(settings.length);
|
|
20991
|
+
for (const [k, v] of settings) {
|
|
20992
|
+
w.text(k);
|
|
20993
|
+
w.text(v);
|
|
20994
|
+
}
|
|
20995
|
+
const schemas = [...state.schemas.values()].sort((a, b) => compareNames(a.name, b.name));
|
|
20996
|
+
w.u32(schemas.length);
|
|
20997
|
+
for (const schema of schemas) {
|
|
20998
|
+
w.text(schema.name);
|
|
20999
|
+
w.u32(schema.oid);
|
|
21000
|
+
const tables = sortedValues(schema.tables);
|
|
21001
|
+
w.u32(tables.length);
|
|
21002
|
+
for (const t of tables) {
|
|
21003
|
+
w.json({
|
|
21004
|
+
name: t.name,
|
|
21005
|
+
schema: t.schema,
|
|
21006
|
+
columns: t.columns,
|
|
21007
|
+
constraints: t.constraints,
|
|
21008
|
+
triggers: t.triggers,
|
|
21009
|
+
temp: t.temp,
|
|
21010
|
+
oid: t.oid
|
|
21011
|
+
});
|
|
21012
|
+
w.u32(t.rows.length);
|
|
21013
|
+
for (const row of t.rows) {
|
|
21014
|
+
w.u32(row.length);
|
|
21015
|
+
for (const d of row) w.datum(d);
|
|
21016
|
+
}
|
|
21017
|
+
}
|
|
21018
|
+
const views = sortedValues(schema.views);
|
|
21019
|
+
w.u32(views.length);
|
|
21020
|
+
for (const v of views) {
|
|
21021
|
+
w.json({
|
|
21022
|
+
name: v.name,
|
|
21023
|
+
schema: v.schema,
|
|
21024
|
+
query: v.query,
|
|
21025
|
+
columns: v.columns,
|
|
21026
|
+
materialized: v.materialized,
|
|
21027
|
+
matColumns: v.matColumns,
|
|
21028
|
+
temp: v.temp,
|
|
21029
|
+
oid: v.oid
|
|
21030
|
+
});
|
|
21031
|
+
if (v.matRows === null) {
|
|
21032
|
+
w.u8(0);
|
|
21033
|
+
} else {
|
|
21034
|
+
w.u8(1);
|
|
21035
|
+
w.u32(v.matRows.length);
|
|
21036
|
+
for (const row of v.matRows) {
|
|
21037
|
+
w.u32(row.length);
|
|
21038
|
+
for (const d of row) w.datum(d);
|
|
21039
|
+
}
|
|
21040
|
+
}
|
|
21041
|
+
}
|
|
21042
|
+
const sequences = sortedValues(schema.sequences);
|
|
21043
|
+
w.u32(sequences.length);
|
|
21044
|
+
for (const s of sequences) w.json(s);
|
|
21045
|
+
const enums = sortedValues(schema.enums);
|
|
21046
|
+
w.u32(enums.length);
|
|
21047
|
+
for (const e of enums) w.json(e);
|
|
21048
|
+
const domains = sortedValues(schema.domains);
|
|
21049
|
+
w.u32(domains.length);
|
|
21050
|
+
for (const d of domains) w.json(d);
|
|
21051
|
+
const functionKeys = [...schema.functions.keys()].sort(compareNames);
|
|
21052
|
+
w.u32(functionKeys.length);
|
|
21053
|
+
for (const key of functionKeys) {
|
|
21054
|
+
w.text(key);
|
|
21055
|
+
const overloads = schema.functions.get(key);
|
|
21056
|
+
w.u32(overloads.length);
|
|
21057
|
+
for (const f of overloads) w.json(f);
|
|
21058
|
+
}
|
|
21059
|
+
const indexes = sortedValues(schema.indexes);
|
|
21060
|
+
w.u32(indexes.length);
|
|
21061
|
+
for (const idx of indexes) w.json(idx);
|
|
21062
|
+
}
|
|
21063
|
+
if (state.lastSequence === null) {
|
|
21064
|
+
w.u8(0);
|
|
21065
|
+
} else {
|
|
21066
|
+
w.u8(1);
|
|
21067
|
+
w.text(state.lastSequence.schema);
|
|
21068
|
+
w.text(state.lastSequence.name);
|
|
21069
|
+
}
|
|
21070
|
+
w.u64(runtime.prngState);
|
|
21071
|
+
w.i64(BigInt(Math.trunc(runtime.nowMs)));
|
|
21072
|
+
return w.finish();
|
|
21073
|
+
}
|
|
21074
|
+
function decodeDatabaseState(snapshot, prng, clock) {
|
|
21075
|
+
try {
|
|
21076
|
+
return decodeInner(snapshot, prng, clock);
|
|
21077
|
+
} catch (error) {
|
|
21078
|
+
if (error instanceof PostgresError) throw error;
|
|
21079
|
+
throw snapshotError();
|
|
21080
|
+
}
|
|
21081
|
+
}
|
|
21082
|
+
function decodeInner(snapshot, prng, clock) {
|
|
21083
|
+
const r = new Reader(snapshot);
|
|
21084
|
+
const magic = r.raw(4);
|
|
21085
|
+
if (!magic.every((byte, index) => byte === MAGIC[index])) {
|
|
21086
|
+
throw new PostgresError("snapshot_format", "invalid postgres-mem snapshot magic", "XX000");
|
|
21087
|
+
}
|
|
21088
|
+
const version = r.u32();
|
|
21089
|
+
if (version !== VERSION) {
|
|
21090
|
+
throw new PostgresError("snapshot_version", `unsupported postgres-mem snapshot version: ${version}`, "XX000");
|
|
21091
|
+
}
|
|
21092
|
+
const state = new DatabaseState(prng, clock);
|
|
21093
|
+
state.oidCounter = r.u32();
|
|
21094
|
+
state.changes = r.u32();
|
|
21095
|
+
state.settings = /* @__PURE__ */ new Map();
|
|
21096
|
+
const settingCount = r.u32();
|
|
21097
|
+
for (let i = 0; i < settingCount; i++) {
|
|
21098
|
+
const k = r.text();
|
|
21099
|
+
state.settings.set(k, r.text());
|
|
21100
|
+
}
|
|
21101
|
+
state.schemas = /* @__PURE__ */ new Map();
|
|
21102
|
+
const schemaCount = r.u32();
|
|
21103
|
+
for (let si = 0; si < schemaCount; si++) {
|
|
21104
|
+
const schema = new SchemaData(r.text(), r.u32());
|
|
21105
|
+
const tableCount = r.u32();
|
|
21106
|
+
for (let i = 0; i < tableCount; i++) {
|
|
21107
|
+
const meta = r.json();
|
|
21108
|
+
const table = new TableData(meta.schema, meta.name, meta.columns, meta.oid, meta.temp);
|
|
21109
|
+
table.constraints = meta.constraints;
|
|
21110
|
+
table.triggers = meta.triggers;
|
|
21111
|
+
const rowCount = r.u32();
|
|
21112
|
+
for (let ri = 0; ri < rowCount; ri++) {
|
|
21113
|
+
const width = r.u32();
|
|
21114
|
+
if (width !== meta.columns.length) throw snapshotError();
|
|
21115
|
+
const row = [];
|
|
21116
|
+
for (let ci = 0; ci < width; ci++) row.push(r.datum());
|
|
21117
|
+
table.rows.push(row);
|
|
21118
|
+
}
|
|
21119
|
+
schema.tables.set(table.name, table);
|
|
21120
|
+
}
|
|
21121
|
+
const viewCount = r.u32();
|
|
21122
|
+
for (let i = 0; i < viewCount; i++) {
|
|
21123
|
+
const meta = r.json();
|
|
21124
|
+
let matRows = null;
|
|
21125
|
+
if (r.u8() === 1) {
|
|
21126
|
+
matRows = [];
|
|
21127
|
+
const rowCount = r.u32();
|
|
21128
|
+
for (let ri = 0; ri < rowCount; ri++) {
|
|
21129
|
+
const width = r.u32();
|
|
21130
|
+
const row = [];
|
|
21131
|
+
for (let ci = 0; ci < width; ci++) row.push(r.datum());
|
|
21132
|
+
matRows.push(row);
|
|
21133
|
+
}
|
|
21134
|
+
}
|
|
21135
|
+
const view = { ...meta, matRows };
|
|
21136
|
+
schema.views.set(view.name, view);
|
|
21137
|
+
}
|
|
21138
|
+
const seqCount = r.u32();
|
|
21139
|
+
for (let i = 0; i < seqCount; i++) {
|
|
21140
|
+
const seq = r.json();
|
|
21141
|
+
schema.sequences.set(seq.name, seq);
|
|
21142
|
+
}
|
|
21143
|
+
const enumCount = r.u32();
|
|
21144
|
+
for (let i = 0; i < enumCount; i++) {
|
|
21145
|
+
const e = r.json();
|
|
21146
|
+
schema.enums.set(e.name, e);
|
|
21147
|
+
}
|
|
21148
|
+
const domainCount = r.u32();
|
|
21149
|
+
for (let i = 0; i < domainCount; i++) {
|
|
21150
|
+
const d = r.json();
|
|
21151
|
+
schema.domains.set(d.name, d);
|
|
21152
|
+
}
|
|
21153
|
+
const fnCount = r.u32();
|
|
21154
|
+
for (let i = 0; i < fnCount; i++) {
|
|
21155
|
+
const key = r.text();
|
|
21156
|
+
const overloadCount = r.u32();
|
|
21157
|
+
const overloads = [];
|
|
21158
|
+
for (let oi = 0; oi < overloadCount; oi++) overloads.push(r.json());
|
|
21159
|
+
schema.functions.set(key, overloads);
|
|
21160
|
+
}
|
|
21161
|
+
const indexCount = r.u32();
|
|
21162
|
+
for (let i = 0; i < indexCount; i++) {
|
|
21163
|
+
const idx = r.json();
|
|
21164
|
+
schema.indexes.set(idx.name, idx);
|
|
21165
|
+
}
|
|
21166
|
+
state.schemas.set(schema.name, schema);
|
|
21167
|
+
}
|
|
21168
|
+
state.lastSequence = r.u8() === 1 ? { schema: r.text(), name: r.text() } : null;
|
|
21169
|
+
if (r.remaining() < 16) throw snapshotError();
|
|
21170
|
+
const runtime = { prngState: r.u64(), nowMs: Number(r.i64()) };
|
|
21171
|
+
if (!r.done()) throw new PostgresError("snapshot_format", "snapshot has trailing data", "XX000");
|
|
21172
|
+
return { state, runtime };
|
|
21173
|
+
}
|
|
21174
|
+
function snapshotError() {
|
|
21175
|
+
return new PostgresError("snapshot_format", "invalid or truncated postgres-mem snapshot", "XX000");
|
|
21176
|
+
}
|
|
21177
|
+
function compareNames(a, b) {
|
|
21178
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
21179
|
+
}
|
|
21180
|
+
function sortedValues(map) {
|
|
21181
|
+
return [...map.values()].sort((a, b) => compareNames(a.name, b.name));
|
|
21182
|
+
}
|
|
21183
|
+
function jsonReplacer(_key, value) {
|
|
21184
|
+
if (typeof value === "bigint") return { $pgmm: "bigint", value: value.toString() };
|
|
21185
|
+
if (value instanceof Uint8Array) return { $pgmm: "bytes", value: Array.from(value) };
|
|
21186
|
+
return value;
|
|
21187
|
+
}
|
|
21188
|
+
function jsonReviver(_key, value) {
|
|
21189
|
+
if (!value || typeof value !== "object" || !("$pgmm" in value)) return value;
|
|
21190
|
+
const tagged = value;
|
|
21191
|
+
if (tagged.$pgmm === "bigint") return BigInt(tagged.value);
|
|
21192
|
+
if (tagged.$pgmm === "bytes") return Uint8Array.from(tagged.value);
|
|
21193
|
+
return value;
|
|
21194
|
+
}
|
|
21195
|
+
registerCodec({ encodeDatabaseState, decodeDatabaseState });
|
|
19586
21196
|
export {
|
|
19587
21197
|
Database,
|
|
19588
21198
|
PostgresError,
|