@crvouga/mockingbird-service-postgres 2.3.0 → 3.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/CHANGELOG.md +21 -1
- package/dist/admin.js +235 -10
- package/dist/admin.js.map +3 -3
- package/dist/executor/comment.d.ts +3 -0
- package/dist/expressions/context.d.ts +2 -0
- package/dist/index.js +235 -10
- package/dist/index.js.map +3 -3
- package/dist/server.js +240 -11
- package/dist/server.js.map +3 -3
- package/dist/sql/deparse-index.d.ts +3 -0
- package/dist/sql/deparse.d.ts +2 -1
- package/dist/storage/database-state.d.ts +4 -0
- package/dist/types/value.d.ts +2 -0
- package/dist/unstable.js +232 -10
- package/dist/unstable.js.map +3 -3
- package/dist/wire/cli.js +240 -11
- package/dist/wire/cli.js.map +3 -3
- package/dist/wire/index.js +240 -11
- package/dist/wire/index.js.map +3 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
# Changelog — @crvouga/mockingbird-service-postgres
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 3.0.0 (2026-10-07)
|
|
4
|
+
|
|
5
|
+
### ⚠️ Breaking changes
|
|
6
|
+
|
|
7
|
+
- point the repo at crvouga/mockingbird ([1bf35a4](https://github.com/crvouga/mockingbird/commit/1bf35a422b84a85b50b09b72bd7cc7093082a86e))
|
|
8
|
+
- point the repo at crvouga/emulates ([cdb5e53](https://github.com/crvouga/mockingbird/commit/cdb5e536ed8c1f52345e3984f089001c25fdb08a))
|
|
9
|
+
- rename Emulators to Emulates ([2e10d9c](https://github.com/crvouga/mockingbird/commit/2e10d9cff84c54ac37768fc9a19d1aefd3943744))
|
|
10
|
+
- rebrand Mockingbird to Emulators ([1adca65](https://github.com/crvouga/mockingbird/commit/1adca65ce28242f11cff98eac05d2be88f680cbe))
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- add index metadata and regressions ([2866d9d](https://github.com/crvouga/mockingbird/commit/2866d9d1242dab51c5c4f655dc107ac4aac2ca57))
|
|
15
|
+
|
|
16
|
+
### Fixes and improvements
|
|
17
|
+
|
|
18
|
+
- typecheck the brand gate before builds ([fc36095](https://github.com/crvouga/mockingbird/commit/fc3609514de70ffe3170a5d216fb8a49f9ce7cbb))
|
|
19
|
+
- serve reconciliation catalog queries ([74a0fb7](https://github.com/crvouga/mockingbird/commit/74a0fb765ff9cd58b5fa61fbeb7db6ca39ec6da4))
|
|
20
|
+
- format the emulates records query ([8698872](https://github.com/crvouga/mockingbird/commit/8698872509d06002be5a8fcdc85d79f8462320c3))
|
|
21
|
+
- complete index regressions ([fa7c0dc](https://github.com/crvouga/mockingbird/commit/fa7c0dc9c76856e0a50db981b7176506d84a1665))
|
|
22
|
+
|
|
23
|
+
## 2.3.0 (2026-10-04)
|
|
4
24
|
|
|
5
25
|
### Features
|
|
6
26
|
|
package/dist/admin.js
CHANGED
|
@@ -1441,6 +1441,9 @@ var PG_CATALOG_RELATIONS = /* @__PURE__ */ new Set([
|
|
|
1441
1441
|
"pg_enum",
|
|
1442
1442
|
"pg_constraint",
|
|
1443
1443
|
"pg_index",
|
|
1444
|
+
"pg_description",
|
|
1445
|
+
"pg_stat_user_tables",
|
|
1446
|
+
"pg_stat_user_indexes",
|
|
1444
1447
|
"pg_sequence",
|
|
1445
1448
|
"pg_sequences",
|
|
1446
1449
|
"pg_tables",
|
|
@@ -3718,6 +3721,7 @@ var TYPE_ALIASES = {
|
|
|
3718
3721
|
regclass: "regclass",
|
|
3719
3722
|
regtype: "regtype",
|
|
3720
3723
|
regproc: "regproc",
|
|
3724
|
+
regnamespace: "regnamespace",
|
|
3721
3725
|
oid: "oid",
|
|
3722
3726
|
void: "void",
|
|
3723
3727
|
record: "record",
|
|
@@ -3811,6 +3815,7 @@ var TYPE_OIDS = {
|
|
|
3811
3815
|
numeric: 1700,
|
|
3812
3816
|
regclass: 2205,
|
|
3813
3817
|
regtype: 2206,
|
|
3818
|
+
regnamespace: 4089,
|
|
3814
3819
|
record: 2249,
|
|
3815
3820
|
uuid: 2950,
|
|
3816
3821
|
jsonb: 3802,
|
|
@@ -4111,6 +4116,7 @@ function recordText(rec, ctx) {
|
|
|
4111
4116
|
return `(${parts.join(",")})`;
|
|
4112
4117
|
}
|
|
4113
4118
|
function datumText(t, v, ctx) {
|
|
4119
|
+
if (t === "regnamespace") return ctx.namespaceName?.(v) ?? String(v);
|
|
4114
4120
|
if (v === null) throw pgError("internal", "datumText called with null");
|
|
4115
4121
|
if (isArrayType(t)) return arrayText(v, ctx);
|
|
4116
4122
|
if (isEnumType(t)) return v;
|
|
@@ -4184,6 +4190,11 @@ function datumText(t, v, ctx) {
|
|
|
4184
4190
|
}
|
|
4185
4191
|
var UTC_INPUT = { zoneOffsetForNaive: () => 0 };
|
|
4186
4192
|
function datumFromText(t, text, ctx) {
|
|
4193
|
+
if (t === "regnamespace") {
|
|
4194
|
+
if (/^\s*\d+\s*$/.test(text)) return datumFromText("oid", text, ctx);
|
|
4195
|
+
if (!ctx.namespaceOid) throw unsupported("regnamespace input without a catalog");
|
|
4196
|
+
return ctx.namespaceOid(text);
|
|
4197
|
+
}
|
|
4187
4198
|
if (isArrayType(t)) return parseArrayText(t, text, ctx);
|
|
4188
4199
|
if (isEnumType(t)) {
|
|
4189
4200
|
if (ctx.enumHasLabel && !ctx.enumHasLabel(t, text)) {
|
|
@@ -5040,7 +5051,11 @@ function castTo(env, value, target, opts = {}) {
|
|
|
5040
5051
|
);
|
|
5041
5052
|
return tv(target, makeArray(toElem, items, arr.dims.slice(), arr.lbs.slice()));
|
|
5042
5053
|
}
|
|
5043
|
-
if (
|
|
5054
|
+
if (from === "oid" && target === "regnamespace") return tv(target, v);
|
|
5055
|
+
if (from === "regnamespace" && (target === "oid" || target === "int4" || target === "int8")) {
|
|
5056
|
+
return tv(target, target === "int8" ? BigInt(v) : v);
|
|
5057
|
+
}
|
|
5058
|
+
if ((from === "int4" || from === "int8" || from === "int2") && (target === "oid" || target === "regclass" || target === "regtype" || target === "regproc" || target === "regnamespace")) {
|
|
5044
5059
|
return tv(target, Number(v));
|
|
5045
5060
|
}
|
|
5046
5061
|
if (from === "oid" && (target === "int4" || target === "int8")) {
|
|
@@ -5988,6 +6003,7 @@ function datumCompare(t, a, b, ctx = DEFAULT_COMPARE_CTX) {
|
|
|
5988
6003
|
case "int2":
|
|
5989
6004
|
case "int4":
|
|
5990
6005
|
case "oid":
|
|
6006
|
+
case "regnamespace":
|
|
5991
6007
|
case "date":
|
|
5992
6008
|
return expectNumber(a, t) - expectNumber(b, t);
|
|
5993
6009
|
case "float4":
|
|
@@ -8143,10 +8159,99 @@ function exactDegTan(x) {
|
|
|
8143
8159
|
}
|
|
8144
8160
|
|
|
8145
8161
|
// src/sql/deparse.ts
|
|
8162
|
+
function deparseSelect(stmt) {
|
|
8163
|
+
return deparseBody(stmt.body);
|
|
8164
|
+
}
|
|
8165
|
+
function deparseBody(body) {
|
|
8166
|
+
switch (body.type) {
|
|
8167
|
+
case "select_core":
|
|
8168
|
+
return deparseSelectCore(body);
|
|
8169
|
+
case "setop":
|
|
8170
|
+
return `${deparseBody(body.left)} ${body.op.toUpperCase()}${body.all ? " ALL" : ""} ${deparseBody(body.right)}`;
|
|
8171
|
+
case "values":
|
|
8172
|
+
return `VALUES ${body.rows.map((r) => `(${r.map(deparseExpr).join(", ")})`).join(", ")}`;
|
|
8173
|
+
}
|
|
8174
|
+
}
|
|
8175
|
+
function deparseSelectCore(body) {
|
|
8176
|
+
const targets = body.targets.length === 0 ? "*" : body.targets.map((t) => {
|
|
8177
|
+
const expr = deparseExpr(t.expr);
|
|
8178
|
+
return t.alias ? `${expr} AS ${quoteIdent(t.alias)}` : expr;
|
|
8179
|
+
}).join(", ");
|
|
8180
|
+
let sql = `SELECT ${targets}`;
|
|
8181
|
+
if (body.from.length > 0) {
|
|
8182
|
+
sql += ` FROM ${body.from.map(deparseFrom).join(", ")}`;
|
|
8183
|
+
}
|
|
8184
|
+
if (body.where) sql += ` WHERE ${deparseExpr(body.where)}`;
|
|
8185
|
+
if (body.groupBy && body.groupBy.length > 0) {
|
|
8186
|
+
sql += ` GROUP BY ${body.groupBy.map((g) => g.kind === "expr" ? deparseExpr(g.expr) : "?").join(", ")}`;
|
|
8187
|
+
}
|
|
8188
|
+
if (body.having) sql += ` HAVING ${deparseExpr(body.having)}`;
|
|
8189
|
+
return sql;
|
|
8190
|
+
}
|
|
8191
|
+
function deparseFrom(item) {
|
|
8192
|
+
if (item.type === "from_table") {
|
|
8193
|
+
const name = item.name.join(".");
|
|
8194
|
+
return item.alias ? `${name} ${quoteIdent(item.alias)}` : name;
|
|
8195
|
+
}
|
|
8196
|
+
return "(subquery)";
|
|
8197
|
+
}
|
|
8146
8198
|
function quoteIdent(name) {
|
|
8147
8199
|
if (/^[a-z_][a-z0-9_$]*$/.test(name)) return name;
|
|
8148
8200
|
return `"${name.replaceAll('"', '""')}"`;
|
|
8149
8201
|
}
|
|
8202
|
+
function deparseExpr(e) {
|
|
8203
|
+
switch (e.type) {
|
|
8204
|
+
case "null_lit":
|
|
8205
|
+
return "NULL";
|
|
8206
|
+
case "string_lit":
|
|
8207
|
+
return `'${e.value.replaceAll("'", "''")}'`;
|
|
8208
|
+
case "number_lit":
|
|
8209
|
+
return e.raw;
|
|
8210
|
+
case "bool_lit":
|
|
8211
|
+
return e.value ? "true" : "false";
|
|
8212
|
+
case "colref":
|
|
8213
|
+
return e.parts.join(".");
|
|
8214
|
+
case "star":
|
|
8215
|
+
return e.table ? `${e.table.join(".")}.*` : "*";
|
|
8216
|
+
case "binop":
|
|
8217
|
+
return `(${deparseExpr(e.left)} ${e.op} ${deparseExpr(e.right)})`;
|
|
8218
|
+
case "unop":
|
|
8219
|
+
return `${e.op}${deparseExpr(e.operand)}`;
|
|
8220
|
+
case "cast":
|
|
8221
|
+
return `CAST(${deparseExpr(e.expr)} AS ${e.target.parts.join(".")})`;
|
|
8222
|
+
case "func":
|
|
8223
|
+
return `${e.name.join(".")}(${e.args.map(deparseExpr).join(", ")})`;
|
|
8224
|
+
case "case": {
|
|
8225
|
+
let out = "CASE";
|
|
8226
|
+
if (e.operand) out += ` ${deparseExpr(e.operand)}`;
|
|
8227
|
+
for (const arm of e.whens) {
|
|
8228
|
+
out += ` WHEN ${deparseExpr(arm.when)} THEN ${deparseExpr(arm.then)}`;
|
|
8229
|
+
}
|
|
8230
|
+
if (e.elseExpr) out += ` ELSE ${deparseExpr(e.elseExpr)}`;
|
|
8231
|
+
return `${out} END`;
|
|
8232
|
+
}
|
|
8233
|
+
case "subquery_expr":
|
|
8234
|
+
return `(${deparseSelect(e.query)})`;
|
|
8235
|
+
default:
|
|
8236
|
+
return "?";
|
|
8237
|
+
}
|
|
8238
|
+
}
|
|
8239
|
+
|
|
8240
|
+
// src/sql/deparse-index.ts
|
|
8241
|
+
function deparseIndexColumn(column) {
|
|
8242
|
+
let result = column.column === null ? deparseExpr(column.expr) : quoteIdent(column.column);
|
|
8243
|
+
if (column.dir === "desc") result += " DESC";
|
|
8244
|
+
const defaultNulls = column.dir === "desc" ? "first" : "last";
|
|
8245
|
+
if (column.nulls !== defaultNulls) result += ` NULLS ${column.nulls.toUpperCase()}`;
|
|
8246
|
+
return result;
|
|
8247
|
+
}
|
|
8248
|
+
function deparseIndex(index) {
|
|
8249
|
+
const columns = index.columns.map(deparseIndexColumn).join(", ");
|
|
8250
|
+
const unique = index.unique ? "UNIQUE " : "";
|
|
8251
|
+
const nulls = index.nullsNotDistinct ? " NULLS NOT DISTINCT" : "";
|
|
8252
|
+
const predicate = index.where ? ` WHERE ${deparseExpr(index.where)}` : "";
|
|
8253
|
+
return `CREATE ${unique}INDEX ${quoteIdent(index.name)} ON ${quoteIdent(index.schema)}.${quoteIdent(index.table)} USING btree (${columns})${nulls}${predicate}`;
|
|
8254
|
+
}
|
|
8150
8255
|
|
|
8151
8256
|
// src/runtime/database-context.ts
|
|
8152
8257
|
var contexts = /* @__PURE__ */ new WeakMap();
|
|
@@ -8237,6 +8342,22 @@ function sequenceNextval(ctx, seq) {
|
|
|
8237
8342
|
}
|
|
8238
8343
|
function getMiscFunctions() {
|
|
8239
8344
|
const m = /* @__PURE__ */ new Map();
|
|
8345
|
+
m.set(
|
|
8346
|
+
"pg_get_indexdef",
|
|
8347
|
+
strict("text", (ctx, args) => {
|
|
8348
|
+
const oid = argInt(ctx, args[0]);
|
|
8349
|
+
const column = args[1] ? argInt(ctx, args[1]) : 0;
|
|
8350
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8351
|
+
for (const index of schema.indexes.values()) {
|
|
8352
|
+
if (index.oid !== oid) continue;
|
|
8353
|
+
if (column === 0) return tv("text", deparseIndex(index));
|
|
8354
|
+
const part = index.columns[column - 1];
|
|
8355
|
+
return tv("text", part ? deparseIndexColumn(part) : "");
|
|
8356
|
+
}
|
|
8357
|
+
}
|
|
8358
|
+
return tv("text", null);
|
|
8359
|
+
})
|
|
8360
|
+
);
|
|
8240
8361
|
m.set("version", () => tv("text", PG_VERSION_TEXT));
|
|
8241
8362
|
m.set("current_database", (ctx) => tv("name", databaseCatalogContext(ctx.state).name));
|
|
8242
8363
|
m.set("current_catalog", (ctx) => tv("name", databaseCatalogContext(ctx.state).name));
|
|
@@ -13457,6 +13578,9 @@ function tryIndexedTableRows(env, table, alias, where) {
|
|
|
13457
13578
|
const key = uniqueKeyOf(env, table, spec, probeRow);
|
|
13458
13579
|
if (key === null) return [];
|
|
13459
13580
|
const hits = indexStoreFor(env, table, spec).lookup(key);
|
|
13581
|
+
const schema = env.ctx.state.schemas.get(table.schema);
|
|
13582
|
+
const index = schema?.indexes.get(spec.name);
|
|
13583
|
+
if (schema && index) schema.indexes.set(spec.name, { ...index, scans: (index.scans ?? 0n) + 1n });
|
|
13460
13584
|
return hits.map((i) => table.rowAt(i));
|
|
13461
13585
|
}
|
|
13462
13586
|
function tryIndexedFromItem(env, item, where) {
|
|
@@ -16219,8 +16343,8 @@ var Parser = class {
|
|
|
16219
16343
|
this.eatKw("column");
|
|
16220
16344
|
const column = this.ident();
|
|
16221
16345
|
let alterType = this.eatKw("type");
|
|
16222
|
-
if (!alterType && this.
|
|
16223
|
-
this.pos +=
|
|
16346
|
+
if (!alterType && this.atKw("set") && this.atKw("data", 1)) {
|
|
16347
|
+
this.pos += 2;
|
|
16224
16348
|
this.expectKw("type");
|
|
16225
16349
|
alterType = true;
|
|
16226
16350
|
}
|
|
@@ -20572,7 +20696,7 @@ function uniqueSpecsFor(env, table) {
|
|
|
20572
20696
|
const schema = env.ctx.state.schemas.get(table.schema);
|
|
20573
20697
|
if (schema) {
|
|
20574
20698
|
for (const idx of schema.indexes.values()) {
|
|
20575
|
-
if (idx.table !== table.name || !idx.unique || idx.isConstraint) continue;
|
|
20699
|
+
if (idx.table !== table.name || !idx.unique || idx.isConstraint || idx.valid === false) continue;
|
|
20576
20700
|
specs.push({
|
|
20577
20701
|
name: idx.name,
|
|
20578
20702
|
keys: idx.columns.map((c) => ({
|
|
@@ -21723,6 +21847,25 @@ var EngineCtx = class {
|
|
|
21723
21847
|
timezone() {
|
|
21724
21848
|
return this.state.getSetting("timezone") ?? "UTC";
|
|
21725
21849
|
}
|
|
21850
|
+
namespaceOid(input) {
|
|
21851
|
+
const trimmed = input.trim();
|
|
21852
|
+
const name = trimmed.startsWith('"') && trimmed.endsWith('"') ? trimmed.slice(1, -1).replaceAll('""', '"') : trimmed.toLowerCase();
|
|
21853
|
+
if (name === "pg_catalog") return 11;
|
|
21854
|
+
if (name === "information_schema") return 13212;
|
|
21855
|
+
const schema = this.state.schemas.get(name);
|
|
21856
|
+
if (!schema) throw pgError("undefined_object", `schema "${name}" does not exist`, "3F000");
|
|
21857
|
+
return schema.oid;
|
|
21858
|
+
}
|
|
21859
|
+
namespaceName(oid) {
|
|
21860
|
+
if (oid === 11) return "pg_catalog";
|
|
21861
|
+
if (oid === 13212) return "information_schema";
|
|
21862
|
+
for (const schema of this.state.schemas.values()) {
|
|
21863
|
+
if (schema.oid === oid) {
|
|
21864
|
+
return /^[a-z_][a-z0-9_$]*$/.test(schema.name) ? schema.name : `"${schema.name.replaceAll('"', '""')}"`;
|
|
21865
|
+
}
|
|
21866
|
+
}
|
|
21867
|
+
return null;
|
|
21868
|
+
}
|
|
21726
21869
|
zoneOffsetAt(utcMicros) {
|
|
21727
21870
|
return zoneOffsetAtUtc(this.timezone(), utcMicros);
|
|
21728
21871
|
}
|
|
@@ -21993,7 +22136,7 @@ function pgClass(ctx) {
|
|
|
21993
22136
|
for (const s of schemaData.sequences.values()) push(s.oid, s.name, s.schema, "S", 3, 1, false, true, s.temp);
|
|
21994
22137
|
for (const i of schemaData.indexes.values()) {
|
|
21995
22138
|
push(
|
|
21996
|
-
state.schemas.get(i.schema)?.tables.get(i.table)?.oid ?? 0,
|
|
22139
|
+
i.oid ?? state.schemas.get(i.schema)?.tables.get(i.table)?.oid ?? 0,
|
|
21997
22140
|
i.name,
|
|
21998
22141
|
i.schema,
|
|
21999
22142
|
"i",
|
|
@@ -22230,7 +22373,15 @@ function pgIndex(ctx) {
|
|
|
22230
22373
|
for (const i of schema.indexes.values()) {
|
|
22231
22374
|
const table = schema.tables.get(i.table);
|
|
22232
22375
|
const isPrimary = i.isConstraint && table?.constraints.some((c) => c.kind === "primary_key" && c.name === i.name) === true;
|
|
22233
|
-
rows.push([
|
|
22376
|
+
rows.push([
|
|
22377
|
+
i.oid ?? table?.oid ?? 0,
|
|
22378
|
+
table?.oid ?? 0,
|
|
22379
|
+
i.columns.length,
|
|
22380
|
+
i.unique,
|
|
22381
|
+
isPrimary,
|
|
22382
|
+
i.where !== null,
|
|
22383
|
+
i.valid !== false
|
|
22384
|
+
]);
|
|
22234
22385
|
}
|
|
22235
22386
|
}
|
|
22236
22387
|
return rel(
|
|
@@ -22240,12 +22391,73 @@ function pgIndex(ctx) {
|
|
|
22240
22391
|
["indnatts", "int2"],
|
|
22241
22392
|
["indisunique", "bool"],
|
|
22242
22393
|
["indisprimary", "bool"],
|
|
22243
|
-
["indpred", "bool"]
|
|
22394
|
+
["indpred", "bool"],
|
|
22395
|
+
["indisvalid", "bool"]
|
|
22244
22396
|
],
|
|
22245
22397
|
rows,
|
|
22246
22398
|
"pg_index"
|
|
22247
22399
|
);
|
|
22248
22400
|
}
|
|
22401
|
+
function pgStatUserTables(ctx) {
|
|
22402
|
+
return rel(
|
|
22403
|
+
[
|
|
22404
|
+
["relid", "oid"],
|
|
22405
|
+
["schemaname", "name"],
|
|
22406
|
+
["relname", "name"],
|
|
22407
|
+
["n_live_tup", "int8"]
|
|
22408
|
+
],
|
|
22409
|
+
[...allTables(ctx.state)].map((table) => [table.oid, table.schema, table.name, BigInt(table.rowCount())]),
|
|
22410
|
+
"pg_stat_user_tables"
|
|
22411
|
+
);
|
|
22412
|
+
}
|
|
22413
|
+
function pgDescription(ctx) {
|
|
22414
|
+
const rows = [];
|
|
22415
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
22416
|
+
for (const index of schema.indexes.values()) {
|
|
22417
|
+
if (index.comment) rows.push([index.oid ?? 0, 1259, 0, index.comment]);
|
|
22418
|
+
}
|
|
22419
|
+
}
|
|
22420
|
+
return rel(
|
|
22421
|
+
[
|
|
22422
|
+
["objoid", "oid"],
|
|
22423
|
+
["classoid", "oid"],
|
|
22424
|
+
["objsubid", "int4"],
|
|
22425
|
+
["description", "text"]
|
|
22426
|
+
],
|
|
22427
|
+
rows,
|
|
22428
|
+
"pg_description"
|
|
22429
|
+
);
|
|
22430
|
+
}
|
|
22431
|
+
function pgStatUserIndexes(ctx) {
|
|
22432
|
+
const rows = [];
|
|
22433
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
22434
|
+
if (schema.name === "pg_catalog" || schema.name === "information_schema" || schema.name.startsWith("pg_toast"))
|
|
22435
|
+
continue;
|
|
22436
|
+
for (const index of schema.indexes.values()) {
|
|
22437
|
+
const table = schema.tables.get(index.table);
|
|
22438
|
+
rows.push([
|
|
22439
|
+
table?.oid ?? 0,
|
|
22440
|
+
index.oid ?? table?.oid ?? 0,
|
|
22441
|
+
schema.name,
|
|
22442
|
+
index.table,
|
|
22443
|
+
index.name,
|
|
22444
|
+
index.scans ?? 0n
|
|
22445
|
+
]);
|
|
22446
|
+
}
|
|
22447
|
+
}
|
|
22448
|
+
return rel(
|
|
22449
|
+
[
|
|
22450
|
+
["relid", "oid"],
|
|
22451
|
+
["indexrelid", "oid"],
|
|
22452
|
+
["schemaname", "name"],
|
|
22453
|
+
["relname", "name"],
|
|
22454
|
+
["indexrelname", "name"],
|
|
22455
|
+
["idx_scan", "int8"]
|
|
22456
|
+
],
|
|
22457
|
+
rows,
|
|
22458
|
+
"pg_stat_user_indexes"
|
|
22459
|
+
);
|
|
22460
|
+
}
|
|
22249
22461
|
function pgSequence(ctx) {
|
|
22250
22462
|
const rows = [];
|
|
22251
22463
|
for (const s of allSequences(ctx.state)) {
|
|
@@ -22360,7 +22572,7 @@ function pgIndexesView(ctx) {
|
|
|
22360
22572
|
const rows = [];
|
|
22361
22573
|
for (const schema of ctx.state.schemas.values()) {
|
|
22362
22574
|
for (const i of schema.indexes.values()) {
|
|
22363
|
-
rows.push([i.schema, i.table, i.name, null,
|
|
22575
|
+
rows.push([i.schema, i.table, i.name, null, deparseIndex(i)]);
|
|
22364
22576
|
}
|
|
22365
22577
|
}
|
|
22366
22578
|
return rel(
|
|
@@ -22681,6 +22893,12 @@ function buildCatalogRelation(ctx, schema, name) {
|
|
|
22681
22893
|
return pgConstraint(ctx);
|
|
22682
22894
|
case "pg_index":
|
|
22683
22895
|
return pgIndex(ctx);
|
|
22896
|
+
case "pg_description":
|
|
22897
|
+
return pgDescription(ctx);
|
|
22898
|
+
case "pg_stat_user_tables":
|
|
22899
|
+
return pgStatUserTables(ctx);
|
|
22900
|
+
case "pg_stat_user_indexes":
|
|
22901
|
+
return pgStatUserIndexes(ctx);
|
|
22684
22902
|
case "pg_sequence":
|
|
22685
22903
|
return pgSequence(ctx);
|
|
22686
22904
|
case "pg_sequences":
|
|
@@ -23264,6 +23482,7 @@ function executeCreateIndex(env, stmt) {
|
|
|
23264
23482
|
}
|
|
23265
23483
|
assertGinTrgmIndex(state, table, stmt);
|
|
23266
23484
|
schema.indexes.set(name, {
|
|
23485
|
+
oid: state.nextOid(),
|
|
23267
23486
|
name,
|
|
23268
23487
|
schema: schema.name,
|
|
23269
23488
|
table: table.name,
|
|
@@ -23276,7 +23495,8 @@ function executeCreateIndex(env, stmt) {
|
|
|
23276
23495
|
})),
|
|
23277
23496
|
where: stmt.where,
|
|
23278
23497
|
nullsNotDistinct: stmt.nullsNotDistinct,
|
|
23279
|
-
isConstraint: false
|
|
23498
|
+
isConstraint: false,
|
|
23499
|
+
valid: true
|
|
23280
23500
|
});
|
|
23281
23501
|
if (stmt.unique) {
|
|
23282
23502
|
try {
|
|
@@ -23284,7 +23504,9 @@ function executeCreateIndex(env, stmt) {
|
|
|
23284
23504
|
checkUnique(env, table, table.rowAt(i), i);
|
|
23285
23505
|
}
|
|
23286
23506
|
} catch (err) {
|
|
23287
|
-
schema.indexes.
|
|
23507
|
+
if (stmt.concurrently) schema.indexes.get(name).valid = false;
|
|
23508
|
+
else schema.indexes.delete(name);
|
|
23509
|
+
table.indexStores = null;
|
|
23288
23510
|
throw err;
|
|
23289
23511
|
}
|
|
23290
23512
|
}
|
|
@@ -24404,6 +24626,9 @@ var Statement = class _Statement {
|
|
|
24404
24626
|
const typed = params.map((p, i) => bindValueToTyped(p, i));
|
|
24405
24627
|
let last = null;
|
|
24406
24628
|
for (const stmt of this.statements) {
|
|
24629
|
+
if (stmt.type === "create_index" && stmt.concurrently && this.database.transactions.inTransaction) {
|
|
24630
|
+
throw pgError("misuse", "CREATE INDEX CONCURRENTLY cannot run inside a transaction block", "25001");
|
|
24631
|
+
}
|
|
24407
24632
|
const env = {
|
|
24408
24633
|
ctx: new EngineCtx(this.database.state),
|
|
24409
24634
|
params: typed,
|