@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/dist/sql/deparse.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { SelectStmt } from "../ast/nodes.js";
|
|
1
|
+
import type { Expr, SelectStmt } from "../ast/nodes.js";
|
|
2
2
|
/** Minimal SELECT deparsing for pg_get_viewdef / information_schema. */
|
|
3
3
|
export declare function deparseSelect(stmt: SelectStmt): string;
|
|
4
4
|
export declare function quoteIdent(name: string): string;
|
|
5
|
+
export declare function deparseExpr(e: Expr): string;
|
|
@@ -42,10 +42,14 @@ export type ConstraintMeta = {
|
|
|
42
42
|
match: "full" | "simple";
|
|
43
43
|
};
|
|
44
44
|
export interface IndexMeta {
|
|
45
|
+
oid?: number;
|
|
45
46
|
name: string;
|
|
46
47
|
schema: string;
|
|
47
48
|
table: string;
|
|
48
49
|
unique: boolean;
|
|
50
|
+
comment?: string | null;
|
|
51
|
+
valid?: boolean;
|
|
52
|
+
scans?: bigint;
|
|
49
53
|
/** simple column indexes store names; expression indexes store the AST */
|
|
50
54
|
columns: Array<{
|
|
51
55
|
column: string | null;
|
package/dist/types/value.d.ts
CHANGED
|
@@ -80,6 +80,7 @@ export declare function parseUuidText(text: string): string;
|
|
|
80
80
|
export declare function parseMoneyText(text: string): bigint;
|
|
81
81
|
export declare function moneyText(cents: bigint): string;
|
|
82
82
|
export interface OutputCtx {
|
|
83
|
+
namespaceName?(oid: number): string | null;
|
|
83
84
|
/** offset seconds east of UTC for rendering timestamptz at given UTC micros */
|
|
84
85
|
zoneOffsetAt(utcMicros: bigint): number;
|
|
85
86
|
}
|
|
@@ -89,6 +90,7 @@ export declare function recordText(rec: PgRecord, ctx: OutputCtx): string;
|
|
|
89
90
|
/** Render a non-null datum of type `t` to PG wire text. */
|
|
90
91
|
export declare function datumText(t: TypeId, v: Datum, ctx: OutputCtx): string;
|
|
91
92
|
export interface InputCtx {
|
|
93
|
+
namespaceOid?(name: string): number;
|
|
92
94
|
/** session zone offset lookup for naive timestamptz input */
|
|
93
95
|
zoneOffsetForNaive(naiveMicros: bigint): number;
|
|
94
96
|
/** enum label validation: returns true when label is valid for the enum type */
|
package/dist/unstable.js
CHANGED
|
@@ -2351,6 +2351,7 @@ var TYPE_ALIASES = {
|
|
|
2351
2351
|
regclass: "regclass",
|
|
2352
2352
|
regtype: "regtype",
|
|
2353
2353
|
regproc: "regproc",
|
|
2354
|
+
regnamespace: "regnamespace",
|
|
2354
2355
|
oid: "oid",
|
|
2355
2356
|
void: "void",
|
|
2356
2357
|
record: "record",
|
|
@@ -2444,6 +2445,7 @@ var TYPE_OIDS = {
|
|
|
2444
2445
|
numeric: 1700,
|
|
2445
2446
|
regclass: 2205,
|
|
2446
2447
|
regtype: 2206,
|
|
2448
|
+
regnamespace: 4089,
|
|
2447
2449
|
record: 2249,
|
|
2448
2450
|
uuid: 2950,
|
|
2449
2451
|
jsonb: 3802,
|
|
@@ -2744,6 +2746,7 @@ function recordText(rec, ctx) {
|
|
|
2744
2746
|
return `(${parts.join(",")})`;
|
|
2745
2747
|
}
|
|
2746
2748
|
function datumText(t, v, ctx) {
|
|
2749
|
+
if (t === "regnamespace") return ctx.namespaceName?.(v) ?? String(v);
|
|
2747
2750
|
if (v === null) throw pgError("internal", "datumText called with null");
|
|
2748
2751
|
if (isArrayType(t)) return arrayText(v, ctx);
|
|
2749
2752
|
if (isEnumType(t)) return v;
|
|
@@ -2817,6 +2820,11 @@ function datumText(t, v, ctx) {
|
|
|
2817
2820
|
}
|
|
2818
2821
|
var UTC_INPUT = { zoneOffsetForNaive: () => 0 };
|
|
2819
2822
|
function datumFromText(t, text, ctx) {
|
|
2823
|
+
if (t === "regnamespace") {
|
|
2824
|
+
if (/^\s*\d+\s*$/.test(text)) return datumFromText("oid", text, ctx);
|
|
2825
|
+
if (!ctx.namespaceOid) throw unsupported("regnamespace input without a catalog");
|
|
2826
|
+
return ctx.namespaceOid(text);
|
|
2827
|
+
}
|
|
2820
2828
|
if (isArrayType(t)) return parseArrayText(t, text, ctx);
|
|
2821
2829
|
if (isEnumType(t)) {
|
|
2822
2830
|
if (ctx.enumHasLabel && !ctx.enumHasLabel(t, text)) {
|
|
@@ -3137,7 +3145,11 @@ function castTo(env, value, target, opts = {}) {
|
|
|
3137
3145
|
);
|
|
3138
3146
|
return tv(target, makeArray(toElem, items, arr.dims.slice(), arr.lbs.slice()));
|
|
3139
3147
|
}
|
|
3140
|
-
if (
|
|
3148
|
+
if (from === "oid" && target === "regnamespace") return tv(target, v);
|
|
3149
|
+
if (from === "regnamespace" && (target === "oid" || target === "int4" || target === "int8")) {
|
|
3150
|
+
return tv(target, target === "int8" ? BigInt(v) : v);
|
|
3151
|
+
}
|
|
3152
|
+
if ((from === "int4" || from === "int8" || from === "int2") && (target === "oid" || target === "regclass" || target === "regtype" || target === "regproc" || target === "regnamespace")) {
|
|
3141
3153
|
return tv(target, Number(v));
|
|
3142
3154
|
}
|
|
3143
3155
|
if (from === "oid" && (target === "int4" || target === "int8")) {
|
|
@@ -3435,6 +3447,7 @@ function datumCompare(t, a, b, ctx = DEFAULT_COMPARE_CTX) {
|
|
|
3435
3447
|
case "int2":
|
|
3436
3448
|
case "int4":
|
|
3437
3449
|
case "oid":
|
|
3450
|
+
case "regnamespace":
|
|
3438
3451
|
case "date":
|
|
3439
3452
|
return expectNumber(a, t) - expectNumber(b, t);
|
|
3440
3453
|
case "float4":
|
|
@@ -6525,10 +6538,99 @@ function exactDegTan(x) {
|
|
|
6525
6538
|
}
|
|
6526
6539
|
|
|
6527
6540
|
// src/sql/deparse.ts
|
|
6541
|
+
function deparseSelect(stmt) {
|
|
6542
|
+
return deparseBody(stmt.body);
|
|
6543
|
+
}
|
|
6544
|
+
function deparseBody(body) {
|
|
6545
|
+
switch (body.type) {
|
|
6546
|
+
case "select_core":
|
|
6547
|
+
return deparseSelectCore(body);
|
|
6548
|
+
case "setop":
|
|
6549
|
+
return `${deparseBody(body.left)} ${body.op.toUpperCase()}${body.all ? " ALL" : ""} ${deparseBody(body.right)}`;
|
|
6550
|
+
case "values":
|
|
6551
|
+
return `VALUES ${body.rows.map((r) => `(${r.map(deparseExpr).join(", ")})`).join(", ")}`;
|
|
6552
|
+
}
|
|
6553
|
+
}
|
|
6554
|
+
function deparseSelectCore(body) {
|
|
6555
|
+
const targets = body.targets.length === 0 ? "*" : body.targets.map((t) => {
|
|
6556
|
+
const expr = deparseExpr(t.expr);
|
|
6557
|
+
return t.alias ? `${expr} AS ${quoteIdent(t.alias)}` : expr;
|
|
6558
|
+
}).join(", ");
|
|
6559
|
+
let sql = `SELECT ${targets}`;
|
|
6560
|
+
if (body.from.length > 0) {
|
|
6561
|
+
sql += ` FROM ${body.from.map(deparseFrom).join(", ")}`;
|
|
6562
|
+
}
|
|
6563
|
+
if (body.where) sql += ` WHERE ${deparseExpr(body.where)}`;
|
|
6564
|
+
if (body.groupBy && body.groupBy.length > 0) {
|
|
6565
|
+
sql += ` GROUP BY ${body.groupBy.map((g) => g.kind === "expr" ? deparseExpr(g.expr) : "?").join(", ")}`;
|
|
6566
|
+
}
|
|
6567
|
+
if (body.having) sql += ` HAVING ${deparseExpr(body.having)}`;
|
|
6568
|
+
return sql;
|
|
6569
|
+
}
|
|
6570
|
+
function deparseFrom(item) {
|
|
6571
|
+
if (item.type === "from_table") {
|
|
6572
|
+
const name = item.name.join(".");
|
|
6573
|
+
return item.alias ? `${name} ${quoteIdent(item.alias)}` : name;
|
|
6574
|
+
}
|
|
6575
|
+
return "(subquery)";
|
|
6576
|
+
}
|
|
6528
6577
|
function quoteIdent(name) {
|
|
6529
6578
|
if (/^[a-z_][a-z0-9_$]*$/.test(name)) return name;
|
|
6530
6579
|
return `"${name.replaceAll('"', '""')}"`;
|
|
6531
6580
|
}
|
|
6581
|
+
function deparseExpr(e) {
|
|
6582
|
+
switch (e.type) {
|
|
6583
|
+
case "null_lit":
|
|
6584
|
+
return "NULL";
|
|
6585
|
+
case "string_lit":
|
|
6586
|
+
return `'${e.value.replaceAll("'", "''")}'`;
|
|
6587
|
+
case "number_lit":
|
|
6588
|
+
return e.raw;
|
|
6589
|
+
case "bool_lit":
|
|
6590
|
+
return e.value ? "true" : "false";
|
|
6591
|
+
case "colref":
|
|
6592
|
+
return e.parts.join(".");
|
|
6593
|
+
case "star":
|
|
6594
|
+
return e.table ? `${e.table.join(".")}.*` : "*";
|
|
6595
|
+
case "binop":
|
|
6596
|
+
return `(${deparseExpr(e.left)} ${e.op} ${deparseExpr(e.right)})`;
|
|
6597
|
+
case "unop":
|
|
6598
|
+
return `${e.op}${deparseExpr(e.operand)}`;
|
|
6599
|
+
case "cast":
|
|
6600
|
+
return `CAST(${deparseExpr(e.expr)} AS ${e.target.parts.join(".")})`;
|
|
6601
|
+
case "func":
|
|
6602
|
+
return `${e.name.join(".")}(${e.args.map(deparseExpr).join(", ")})`;
|
|
6603
|
+
case "case": {
|
|
6604
|
+
let out = "CASE";
|
|
6605
|
+
if (e.operand) out += ` ${deparseExpr(e.operand)}`;
|
|
6606
|
+
for (const arm of e.whens) {
|
|
6607
|
+
out += ` WHEN ${deparseExpr(arm.when)} THEN ${deparseExpr(arm.then)}`;
|
|
6608
|
+
}
|
|
6609
|
+
if (e.elseExpr) out += ` ELSE ${deparseExpr(e.elseExpr)}`;
|
|
6610
|
+
return `${out} END`;
|
|
6611
|
+
}
|
|
6612
|
+
case "subquery_expr":
|
|
6613
|
+
return `(${deparseSelect(e.query)})`;
|
|
6614
|
+
default:
|
|
6615
|
+
return "?";
|
|
6616
|
+
}
|
|
6617
|
+
}
|
|
6618
|
+
|
|
6619
|
+
// src/sql/deparse-index.ts
|
|
6620
|
+
function deparseIndexColumn(column) {
|
|
6621
|
+
let result = column.column === null ? deparseExpr(column.expr) : quoteIdent(column.column);
|
|
6622
|
+
if (column.dir === "desc") result += " DESC";
|
|
6623
|
+
const defaultNulls = column.dir === "desc" ? "first" : "last";
|
|
6624
|
+
if (column.nulls !== defaultNulls) result += ` NULLS ${column.nulls.toUpperCase()}`;
|
|
6625
|
+
return result;
|
|
6626
|
+
}
|
|
6627
|
+
function deparseIndex(index) {
|
|
6628
|
+
const columns = index.columns.map(deparseIndexColumn).join(", ");
|
|
6629
|
+
const unique = index.unique ? "UNIQUE " : "";
|
|
6630
|
+
const nulls = index.nullsNotDistinct ? " NULLS NOT DISTINCT" : "";
|
|
6631
|
+
const predicate = index.where ? ` WHERE ${deparseExpr(index.where)}` : "";
|
|
6632
|
+
return `CREATE ${unique}INDEX ${quoteIdent(index.name)} ON ${quoteIdent(index.schema)}.${quoteIdent(index.table)} USING btree (${columns})${nulls}${predicate}`;
|
|
6633
|
+
}
|
|
6532
6634
|
|
|
6533
6635
|
// src/runtime/database-context.ts
|
|
6534
6636
|
var contexts = /* @__PURE__ */ new WeakMap();
|
|
@@ -6619,6 +6721,22 @@ function sequenceNextval(ctx, seq) {
|
|
|
6619
6721
|
}
|
|
6620
6722
|
function getMiscFunctions() {
|
|
6621
6723
|
const m = /* @__PURE__ */ new Map();
|
|
6724
|
+
m.set(
|
|
6725
|
+
"pg_get_indexdef",
|
|
6726
|
+
strict("text", (ctx, args) => {
|
|
6727
|
+
const oid = argInt(ctx, args[0]);
|
|
6728
|
+
const column = args[1] ? argInt(ctx, args[1]) : 0;
|
|
6729
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
6730
|
+
for (const index of schema.indexes.values()) {
|
|
6731
|
+
if (index.oid !== oid) continue;
|
|
6732
|
+
if (column === 0) return tv("text", deparseIndex(index));
|
|
6733
|
+
const part = index.columns[column - 1];
|
|
6734
|
+
return tv("text", part ? deparseIndexColumn(part) : "");
|
|
6735
|
+
}
|
|
6736
|
+
}
|
|
6737
|
+
return tv("text", null);
|
|
6738
|
+
})
|
|
6739
|
+
);
|
|
6622
6740
|
m.set("version", () => tv("text", PG_VERSION_TEXT));
|
|
6623
6741
|
m.set("current_database", (ctx) => tv("name", databaseCatalogContext(ctx.state).name));
|
|
6624
6742
|
m.set("current_catalog", (ctx) => tv("name", databaseCatalogContext(ctx.state).name));
|
|
@@ -8483,6 +8601,9 @@ var PG_CATALOG_RELATIONS = /* @__PURE__ */ new Set([
|
|
|
8483
8601
|
"pg_enum",
|
|
8484
8602
|
"pg_constraint",
|
|
8485
8603
|
"pg_index",
|
|
8604
|
+
"pg_description",
|
|
8605
|
+
"pg_stat_user_tables",
|
|
8606
|
+
"pg_stat_user_indexes",
|
|
8486
8607
|
"pg_sequence",
|
|
8487
8608
|
"pg_sequences",
|
|
8488
8609
|
"pg_tables",
|
|
@@ -8605,7 +8726,7 @@ function pgClass(ctx) {
|
|
|
8605
8726
|
for (const s of schemaData.sequences.values()) push(s.oid, s.name, s.schema, "S", 3, 1, false, true, s.temp);
|
|
8606
8727
|
for (const i of schemaData.indexes.values()) {
|
|
8607
8728
|
push(
|
|
8608
|
-
state.schemas.get(i.schema)?.tables.get(i.table)?.oid ?? 0,
|
|
8729
|
+
i.oid ?? state.schemas.get(i.schema)?.tables.get(i.table)?.oid ?? 0,
|
|
8609
8730
|
i.name,
|
|
8610
8731
|
i.schema,
|
|
8611
8732
|
"i",
|
|
@@ -8842,7 +8963,15 @@ function pgIndex(ctx) {
|
|
|
8842
8963
|
for (const i of schema.indexes.values()) {
|
|
8843
8964
|
const table = schema.tables.get(i.table);
|
|
8844
8965
|
const isPrimary = i.isConstraint && table?.constraints.some((c) => c.kind === "primary_key" && c.name === i.name) === true;
|
|
8845
|
-
rows.push([
|
|
8966
|
+
rows.push([
|
|
8967
|
+
i.oid ?? table?.oid ?? 0,
|
|
8968
|
+
table?.oid ?? 0,
|
|
8969
|
+
i.columns.length,
|
|
8970
|
+
i.unique,
|
|
8971
|
+
isPrimary,
|
|
8972
|
+
i.where !== null,
|
|
8973
|
+
i.valid !== false
|
|
8974
|
+
]);
|
|
8846
8975
|
}
|
|
8847
8976
|
}
|
|
8848
8977
|
return rel(
|
|
@@ -8852,12 +8981,73 @@ function pgIndex(ctx) {
|
|
|
8852
8981
|
["indnatts", "int2"],
|
|
8853
8982
|
["indisunique", "bool"],
|
|
8854
8983
|
["indisprimary", "bool"],
|
|
8855
|
-
["indpred", "bool"]
|
|
8984
|
+
["indpred", "bool"],
|
|
8985
|
+
["indisvalid", "bool"]
|
|
8856
8986
|
],
|
|
8857
8987
|
rows,
|
|
8858
8988
|
"pg_index"
|
|
8859
8989
|
);
|
|
8860
8990
|
}
|
|
8991
|
+
function pgStatUserTables(ctx) {
|
|
8992
|
+
return rel(
|
|
8993
|
+
[
|
|
8994
|
+
["relid", "oid"],
|
|
8995
|
+
["schemaname", "name"],
|
|
8996
|
+
["relname", "name"],
|
|
8997
|
+
["n_live_tup", "int8"]
|
|
8998
|
+
],
|
|
8999
|
+
[...allTables(ctx.state)].map((table) => [table.oid, table.schema, table.name, BigInt(table.rowCount())]),
|
|
9000
|
+
"pg_stat_user_tables"
|
|
9001
|
+
);
|
|
9002
|
+
}
|
|
9003
|
+
function pgDescription(ctx) {
|
|
9004
|
+
const rows = [];
|
|
9005
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
9006
|
+
for (const index of schema.indexes.values()) {
|
|
9007
|
+
if (index.comment) rows.push([index.oid ?? 0, 1259, 0, index.comment]);
|
|
9008
|
+
}
|
|
9009
|
+
}
|
|
9010
|
+
return rel(
|
|
9011
|
+
[
|
|
9012
|
+
["objoid", "oid"],
|
|
9013
|
+
["classoid", "oid"],
|
|
9014
|
+
["objsubid", "int4"],
|
|
9015
|
+
["description", "text"]
|
|
9016
|
+
],
|
|
9017
|
+
rows,
|
|
9018
|
+
"pg_description"
|
|
9019
|
+
);
|
|
9020
|
+
}
|
|
9021
|
+
function pgStatUserIndexes(ctx) {
|
|
9022
|
+
const rows = [];
|
|
9023
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
9024
|
+
if (schema.name === "pg_catalog" || schema.name === "information_schema" || schema.name.startsWith("pg_toast"))
|
|
9025
|
+
continue;
|
|
9026
|
+
for (const index of schema.indexes.values()) {
|
|
9027
|
+
const table = schema.tables.get(index.table);
|
|
9028
|
+
rows.push([
|
|
9029
|
+
table?.oid ?? 0,
|
|
9030
|
+
index.oid ?? table?.oid ?? 0,
|
|
9031
|
+
schema.name,
|
|
9032
|
+
index.table,
|
|
9033
|
+
index.name,
|
|
9034
|
+
index.scans ?? 0n
|
|
9035
|
+
]);
|
|
9036
|
+
}
|
|
9037
|
+
}
|
|
9038
|
+
return rel(
|
|
9039
|
+
[
|
|
9040
|
+
["relid", "oid"],
|
|
9041
|
+
["indexrelid", "oid"],
|
|
9042
|
+
["schemaname", "name"],
|
|
9043
|
+
["relname", "name"],
|
|
9044
|
+
["indexrelname", "name"],
|
|
9045
|
+
["idx_scan", "int8"]
|
|
9046
|
+
],
|
|
9047
|
+
rows,
|
|
9048
|
+
"pg_stat_user_indexes"
|
|
9049
|
+
);
|
|
9050
|
+
}
|
|
8861
9051
|
function pgSequence(ctx) {
|
|
8862
9052
|
const rows = [];
|
|
8863
9053
|
for (const s of allSequences(ctx.state)) {
|
|
@@ -8972,7 +9162,7 @@ function pgIndexesView(ctx) {
|
|
|
8972
9162
|
const rows = [];
|
|
8973
9163
|
for (const schema of ctx.state.schemas.values()) {
|
|
8974
9164
|
for (const i of schema.indexes.values()) {
|
|
8975
|
-
rows.push([i.schema, i.table, i.name, null,
|
|
9165
|
+
rows.push([i.schema, i.table, i.name, null, deparseIndex(i)]);
|
|
8976
9166
|
}
|
|
8977
9167
|
}
|
|
8978
9168
|
return rel(
|
|
@@ -9293,6 +9483,12 @@ function buildCatalogRelation(ctx, schema, name) {
|
|
|
9293
9483
|
return pgConstraint(ctx);
|
|
9294
9484
|
case "pg_index":
|
|
9295
9485
|
return pgIndex(ctx);
|
|
9486
|
+
case "pg_description":
|
|
9487
|
+
return pgDescription(ctx);
|
|
9488
|
+
case "pg_stat_user_tables":
|
|
9489
|
+
return pgStatUserTables(ctx);
|
|
9490
|
+
case "pg_stat_user_indexes":
|
|
9491
|
+
return pgStatUserIndexes(ctx);
|
|
9296
9492
|
case "pg_sequence":
|
|
9297
9493
|
return pgSequence(ctx);
|
|
9298
9494
|
case "pg_sequences":
|
|
@@ -12068,8 +12264,8 @@ var Parser = class {
|
|
|
12068
12264
|
this.eatKw("column");
|
|
12069
12265
|
const column = this.ident();
|
|
12070
12266
|
let alterType = this.eatKw("type");
|
|
12071
|
-
if (!alterType && this.
|
|
12072
|
-
this.pos +=
|
|
12267
|
+
if (!alterType && this.atKw("set") && this.atKw("data", 1)) {
|
|
12268
|
+
this.pos += 2;
|
|
12073
12269
|
this.expectKw("type");
|
|
12074
12270
|
alterType = true;
|
|
12075
12271
|
}
|
|
@@ -16470,7 +16666,7 @@ function uniqueSpecsFor(env, table) {
|
|
|
16470
16666
|
const schema = env.ctx.state.schemas.get(table.schema);
|
|
16471
16667
|
if (schema) {
|
|
16472
16668
|
for (const idx of schema.indexes.values()) {
|
|
16473
|
-
if (idx.table !== table.name || !idx.unique || idx.isConstraint) continue;
|
|
16669
|
+
if (idx.table !== table.name || !idx.unique || idx.isConstraint || idx.valid === false) continue;
|
|
16474
16670
|
specs.push({
|
|
16475
16671
|
name: idx.name,
|
|
16476
16672
|
keys: idx.columns.map((c) => ({
|
|
@@ -16652,6 +16848,9 @@ function tryIndexedTableRows(env, table, alias, where) {
|
|
|
16652
16848
|
const key = uniqueKeyOf(env, table, spec, probeRow);
|
|
16653
16849
|
if (key === null) return [];
|
|
16654
16850
|
const hits = indexStoreFor(env, table, spec).lookup(key);
|
|
16851
|
+
const schema = env.ctx.state.schemas.get(table.schema);
|
|
16852
|
+
const index = schema?.indexes.get(spec.name);
|
|
16853
|
+
if (schema && index) schema.indexes.set(spec.name, { ...index, scans: (index.scans ?? 0n) + 1n });
|
|
16655
16854
|
return hits.map((i) => table.rowAt(i));
|
|
16656
16855
|
}
|
|
16657
16856
|
function tryIndexedFromItem(env, item, where) {
|
|
@@ -19836,6 +20035,25 @@ var EngineCtx = class {
|
|
|
19836
20035
|
timezone() {
|
|
19837
20036
|
return this.state.getSetting("timezone") ?? "UTC";
|
|
19838
20037
|
}
|
|
20038
|
+
namespaceOid(input) {
|
|
20039
|
+
const trimmed = input.trim();
|
|
20040
|
+
const name = trimmed.startsWith('"') && trimmed.endsWith('"') ? trimmed.slice(1, -1).replaceAll('""', '"') : trimmed.toLowerCase();
|
|
20041
|
+
if (name === "pg_catalog") return 11;
|
|
20042
|
+
if (name === "information_schema") return 13212;
|
|
20043
|
+
const schema = this.state.schemas.get(name);
|
|
20044
|
+
if (!schema) throw pgError("undefined_object", `schema "${name}" does not exist`, "3F000");
|
|
20045
|
+
return schema.oid;
|
|
20046
|
+
}
|
|
20047
|
+
namespaceName(oid) {
|
|
20048
|
+
if (oid === 11) return "pg_catalog";
|
|
20049
|
+
if (oid === 13212) return "information_schema";
|
|
20050
|
+
for (const schema of this.state.schemas.values()) {
|
|
20051
|
+
if (schema.oid === oid) {
|
|
20052
|
+
return /^[a-z_][a-z0-9_$]*$/.test(schema.name) ? schema.name : `"${schema.name.replaceAll('"', '""')}"`;
|
|
20053
|
+
}
|
|
20054
|
+
}
|
|
20055
|
+
return null;
|
|
20056
|
+
}
|
|
19839
20057
|
zoneOffsetAt(utcMicros) {
|
|
19840
20058
|
return zoneOffsetAtUtc(this.timezone(), utcMicros);
|
|
19841
20059
|
}
|
|
@@ -20730,6 +20948,7 @@ function executeCreateIndex(env, stmt) {
|
|
|
20730
20948
|
}
|
|
20731
20949
|
assertGinTrgmIndex(state, table, stmt);
|
|
20732
20950
|
schema.indexes.set(name, {
|
|
20951
|
+
oid: state.nextOid(),
|
|
20733
20952
|
name,
|
|
20734
20953
|
schema: schema.name,
|
|
20735
20954
|
table: table.name,
|
|
@@ -20742,7 +20961,8 @@ function executeCreateIndex(env, stmt) {
|
|
|
20742
20961
|
})),
|
|
20743
20962
|
where: stmt.where,
|
|
20744
20963
|
nullsNotDistinct: stmt.nullsNotDistinct,
|
|
20745
|
-
isConstraint: false
|
|
20964
|
+
isConstraint: false,
|
|
20965
|
+
valid: true
|
|
20746
20966
|
});
|
|
20747
20967
|
if (stmt.unique) {
|
|
20748
20968
|
try {
|
|
@@ -20750,7 +20970,9 @@ function executeCreateIndex(env, stmt) {
|
|
|
20750
20970
|
checkUnique(env, table, table.rowAt(i), i);
|
|
20751
20971
|
}
|
|
20752
20972
|
} catch (err) {
|
|
20753
|
-
schema.indexes.
|
|
20973
|
+
if (stmt.concurrently) schema.indexes.get(name).valid = false;
|
|
20974
|
+
else schema.indexes.delete(name);
|
|
20975
|
+
table.indexStores = null;
|
|
20754
20976
|
throw err;
|
|
20755
20977
|
}
|
|
20756
20978
|
}
|