@crvouga/mockingbird-service-postgres 1.5.0 → 1.6.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/AGENTS.md +5 -6
- package/CHANGELOG.md +17 -1
- package/COMPATIBILITY.md +10 -5
- package/README.md +23 -13
- package/dist/admin.js +129 -43
- package/dist/admin.js.map +4 -4
- package/dist/ast/nodes.d.ts +1 -0
- package/dist/index.js +118 -32
- package/dist/index.js.map +3 -3
- package/dist/runtime/database-context.d.ts +4 -0
- package/dist/sql/deparse.d.ts +1 -0
- package/dist/unstable.js +96 -31
- package/dist/unstable.js.map +3 -3
- package/dist/wire/cli.js +586 -76
- package/dist/wire/cli.js.map +3 -3
- package/dist/wire/cluster.d.ts +20 -8
- package/dist/wire/connection.d.ts +25 -1
- package/dist/wire/index.d.ts +5 -1
- package/dist/wire/index.js +586 -76
- package/dist/wire/index.js.map +3 -3
- package/dist/wire/protocol.d.ts +4 -0
- package/package.json +1 -1
package/dist/sql/deparse.d.ts
CHANGED
package/dist/unstable.js
CHANGED
|
@@ -6524,6 +6524,19 @@ function exactDegTan(x) {
|
|
|
6524
6524
|
return Math.tan(x * Math.PI / 180);
|
|
6525
6525
|
}
|
|
6526
6526
|
|
|
6527
|
+
// src/sql/deparse.ts
|
|
6528
|
+
function quoteIdent(name) {
|
|
6529
|
+
if (/^[a-z_][a-z0-9_$]*$/.test(name)) return name;
|
|
6530
|
+
return `"${name.replaceAll('"', '""')}"`;
|
|
6531
|
+
}
|
|
6532
|
+
|
|
6533
|
+
// src/runtime/database-context.ts
|
|
6534
|
+
var contexts = /* @__PURE__ */ new WeakMap();
|
|
6535
|
+
var fallback = { name: "postgres", names: () => ["postgres"] };
|
|
6536
|
+
function databaseCatalogContext(state) {
|
|
6537
|
+
return contexts.get(state) ?? fallback;
|
|
6538
|
+
}
|
|
6539
|
+
|
|
6527
6540
|
// src/functions/misc-fns.ts
|
|
6528
6541
|
var PG_VERSION_TEXT = "PostgreSQL 18.3 (postgres-mem) on TypeScript, in-memory engine";
|
|
6529
6542
|
function findSequenceForCall(ctx, name) {
|
|
@@ -6607,8 +6620,8 @@ function sequenceNextval(ctx, seq) {
|
|
|
6607
6620
|
function getMiscFunctions() {
|
|
6608
6621
|
const m = /* @__PURE__ */ new Map();
|
|
6609
6622
|
m.set("version", () => tv("text", PG_VERSION_TEXT));
|
|
6610
|
-
m.set("current_database", () => tv("name",
|
|
6611
|
-
m.set("current_catalog", () => tv("name",
|
|
6623
|
+
m.set("current_database", (ctx) => tv("name", databaseCatalogContext(ctx.state).name));
|
|
6624
|
+
m.set("current_catalog", (ctx) => tv("name", databaseCatalogContext(ctx.state).name));
|
|
6612
6625
|
m.set("current_schema", (ctx) => {
|
|
6613
6626
|
const path = ctx.state.effectiveSearchPath();
|
|
6614
6627
|
const first = path.find((s) => ctx.state.schemas.has(s));
|
|
@@ -6730,7 +6743,7 @@ function getMiscFunctions() {
|
|
|
6730
6743
|
if (!col.identity) return tv("text", null);
|
|
6731
6744
|
return tv(
|
|
6732
6745
|
"text",
|
|
6733
|
-
col.identity.sequence.split(".").map(
|
|
6746
|
+
col.identity.sequence.split(".").map(quoteIdent).join(".")
|
|
6734
6747
|
);
|
|
6735
6748
|
})
|
|
6736
6749
|
);
|
|
@@ -8989,7 +9002,8 @@ function pgSettings(ctx) {
|
|
|
8989
9002
|
"pg_settings"
|
|
8990
9003
|
);
|
|
8991
9004
|
}
|
|
8992
|
-
function pgDatabase() {
|
|
9005
|
+
function pgDatabase(ctx) {
|
|
9006
|
+
const names = databaseCatalogContext(ctx.state).names();
|
|
8993
9007
|
return rel(
|
|
8994
9008
|
[
|
|
8995
9009
|
["oid", "oid"],
|
|
@@ -8998,7 +9012,7 @@ function pgDatabase() {
|
|
|
8998
9012
|
["datistemplate", "bool"],
|
|
8999
9013
|
["datallowconn", "bool"]
|
|
9000
9014
|
],
|
|
9001
|
-
[
|
|
9015
|
+
names.map((name, index) => [5 + index, name, 6, false, true]),
|
|
9002
9016
|
"pg_database"
|
|
9003
9017
|
);
|
|
9004
9018
|
}
|
|
@@ -9033,13 +9047,14 @@ function pgTrigger(ctx) {
|
|
|
9033
9047
|
"pg_trigger"
|
|
9034
9048
|
);
|
|
9035
9049
|
}
|
|
9036
|
-
var
|
|
9050
|
+
var catalogName = (state) => databaseCatalogContext(state).name;
|
|
9037
9051
|
function infoSchemata(state) {
|
|
9052
|
+
const catalog = catalogName(state);
|
|
9038
9053
|
const rows = [
|
|
9039
|
-
[
|
|
9040
|
-
[
|
|
9054
|
+
[catalog, "pg_catalog", OWNER],
|
|
9055
|
+
[catalog, "information_schema", OWNER]
|
|
9041
9056
|
];
|
|
9042
|
-
for (const s of state.schemas.values()) rows.push([
|
|
9057
|
+
for (const s of state.schemas.values()) rows.push([catalog, s.name, OWNER]);
|
|
9043
9058
|
return rel(
|
|
9044
9059
|
[
|
|
9045
9060
|
["catalog_name", "name"],
|
|
@@ -9051,13 +9066,14 @@ function infoSchemata(state) {
|
|
|
9051
9066
|
);
|
|
9052
9067
|
}
|
|
9053
9068
|
function infoTables(ctx) {
|
|
9069
|
+
const catalog = catalogName(ctx.state);
|
|
9054
9070
|
const rows = [];
|
|
9055
9071
|
for (const schema of ctx.state.schemas.values()) {
|
|
9056
9072
|
for (const t of schema.tables.values()) {
|
|
9057
|
-
rows.push([
|
|
9073
|
+
rows.push([catalog, t.schema, t.name, t.temp ? "LOCAL TEMPORARY" : "BASE TABLE", "YES"]);
|
|
9058
9074
|
}
|
|
9059
9075
|
for (const v of schema.views.values()) {
|
|
9060
|
-
if (!v.materialized) rows.push([
|
|
9076
|
+
if (!v.materialized) rows.push([catalog, v.schema, v.name, "VIEW", "NO"]);
|
|
9061
9077
|
}
|
|
9062
9078
|
}
|
|
9063
9079
|
return rel(
|
|
@@ -9073,6 +9089,7 @@ function infoTables(ctx) {
|
|
|
9073
9089
|
);
|
|
9074
9090
|
}
|
|
9075
9091
|
function infoColumns(ctx) {
|
|
9092
|
+
const catalog = catalogName(ctx.state);
|
|
9076
9093
|
const rows = [];
|
|
9077
9094
|
for (const t of allTables(ctx.state)) {
|
|
9078
9095
|
t.columns.forEach((c, i) => {
|
|
@@ -9083,7 +9100,7 @@ function infoColumns(ctx) {
|
|
|
9083
9100
|
const dataType = isArrayType(id) ? "ARRAY" : isEnumType(id) ? "USER-DEFINED" : typeDisplayName(id);
|
|
9084
9101
|
const udt = isArrayType(id) ? `_${arrayUdt(id)}` : isEnumType(id) ? id.slice(5).split(".").pop() : id;
|
|
9085
9102
|
rows.push([
|
|
9086
|
-
|
|
9103
|
+
catalog,
|
|
9087
9104
|
t.schema,
|
|
9088
9105
|
t.name,
|
|
9089
9106
|
c.name,
|
|
@@ -9128,10 +9145,11 @@ function arrayUdt(t) {
|
|
|
9128
9145
|
return isEnumType(elem) ? elem.slice(5).split(".").pop() : elem;
|
|
9129
9146
|
}
|
|
9130
9147
|
function infoViews(ctx) {
|
|
9148
|
+
const catalog = catalogName(ctx.state);
|
|
9131
9149
|
const rows = [];
|
|
9132
9150
|
for (const schema of ctx.state.schemas.values()) {
|
|
9133
9151
|
for (const v of schema.views.values()) {
|
|
9134
|
-
if (!v.materialized) rows.push([
|
|
9152
|
+
if (!v.materialized) rows.push([catalog, v.schema, v.name, null]);
|
|
9135
9153
|
}
|
|
9136
9154
|
}
|
|
9137
9155
|
return rel(
|
|
@@ -9146,10 +9164,11 @@ function infoViews(ctx) {
|
|
|
9146
9164
|
);
|
|
9147
9165
|
}
|
|
9148
9166
|
function infoSequences(ctx) {
|
|
9167
|
+
const catalog = catalogName(ctx.state);
|
|
9149
9168
|
const rows = [];
|
|
9150
9169
|
for (const s of allSequences(ctx.state)) {
|
|
9151
9170
|
rows.push([
|
|
9152
|
-
|
|
9171
|
+
catalog,
|
|
9153
9172
|
s.schema,
|
|
9154
9173
|
s.name,
|
|
9155
9174
|
typeDisplayName(s.dataType),
|
|
@@ -9177,11 +9196,12 @@ function infoSequences(ctx) {
|
|
|
9177
9196
|
);
|
|
9178
9197
|
}
|
|
9179
9198
|
function infoTableConstraints(ctx) {
|
|
9199
|
+
const catalog = catalogName(ctx.state);
|
|
9180
9200
|
const rows = [];
|
|
9181
9201
|
for (const t of allTables(ctx.state)) {
|
|
9182
9202
|
for (const c of t.constraints) {
|
|
9183
9203
|
const type = c.kind === "primary_key" ? "PRIMARY KEY" : c.kind === "unique" ? "UNIQUE" : c.kind === "check" ? "CHECK" : "FOREIGN KEY";
|
|
9184
|
-
rows.push([
|
|
9204
|
+
rows.push([catalog, t.schema, c.name, catalog, t.schema, t.name, type]);
|
|
9185
9205
|
}
|
|
9186
9206
|
}
|
|
9187
9207
|
return rel(
|
|
@@ -9199,12 +9219,13 @@ function infoTableConstraints(ctx) {
|
|
|
9199
9219
|
);
|
|
9200
9220
|
}
|
|
9201
9221
|
function infoKeyColumnUsage(ctx) {
|
|
9222
|
+
const catalog = catalogName(ctx.state);
|
|
9202
9223
|
const rows = [];
|
|
9203
9224
|
for (const t of allTables(ctx.state)) {
|
|
9204
9225
|
for (const c of t.constraints) {
|
|
9205
9226
|
if (c.kind !== "primary_key" && c.kind !== "unique" && c.kind !== "foreign_key") continue;
|
|
9206
9227
|
c.columns.forEach((col, i) => {
|
|
9207
|
-
rows.push([
|
|
9228
|
+
rows.push([catalog, t.schema, c.name, catalog, t.schema, t.name, col, i + 1]);
|
|
9208
9229
|
});
|
|
9209
9230
|
}
|
|
9210
9231
|
}
|
|
@@ -9224,12 +9245,13 @@ function infoKeyColumnUsage(ctx) {
|
|
|
9224
9245
|
);
|
|
9225
9246
|
}
|
|
9226
9247
|
function infoRoutines(ctx) {
|
|
9248
|
+
const catalog = catalogName(ctx.state);
|
|
9227
9249
|
const rows = [];
|
|
9228
9250
|
for (const schema of ctx.state.schemas.values()) {
|
|
9229
9251
|
for (const fns of schema.functions.values()) {
|
|
9230
9252
|
for (const f of fns) {
|
|
9231
9253
|
rows.push([
|
|
9232
|
-
|
|
9254
|
+
catalog,
|
|
9233
9255
|
f.schema,
|
|
9234
9256
|
f.name,
|
|
9235
9257
|
"FUNCTION",
|
|
@@ -9286,7 +9308,7 @@ function buildCatalogRelation(ctx, schema, name) {
|
|
|
9286
9308
|
case "pg_settings":
|
|
9287
9309
|
return pgSettings(ctx);
|
|
9288
9310
|
case "pg_database":
|
|
9289
|
-
return pgDatabase();
|
|
9311
|
+
return pgDatabase(ctx);
|
|
9290
9312
|
case "pg_roles":
|
|
9291
9313
|
case "pg_user":
|
|
9292
9314
|
return pgRoles();
|
|
@@ -11438,14 +11460,19 @@ var Parser = class {
|
|
|
11438
11460
|
parseIdentityOptions() {
|
|
11439
11461
|
const options = {};
|
|
11440
11462
|
if (this.eatPunct("(")) {
|
|
11441
|
-
Object.assign(options, this.parseSequenceOptions());
|
|
11463
|
+
Object.assign(options, this.parseSequenceOptions(true));
|
|
11442
11464
|
this.expectPunct(")");
|
|
11443
11465
|
}
|
|
11444
11466
|
return options;
|
|
11445
11467
|
}
|
|
11446
|
-
parseSequenceOptions() {
|
|
11468
|
+
parseSequenceOptions(identity = false) {
|
|
11447
11469
|
const options = {};
|
|
11448
11470
|
for (; ; ) {
|
|
11471
|
+
if (identity && this.eatKw("sequence")) {
|
|
11472
|
+
this.expectKw("name");
|
|
11473
|
+
options.sequenceName = this.qualifiedName();
|
|
11474
|
+
continue;
|
|
11475
|
+
}
|
|
11449
11476
|
if (this.eatKw("increment")) {
|
|
11450
11477
|
this.eatKw("by");
|
|
11451
11478
|
options.increment = this.parseSignedBigInt();
|
|
@@ -20020,7 +20047,13 @@ var DatabaseState = class _DatabaseState {
|
|
|
20020
20047
|
this.settings.set("lc_numeric", "C");
|
|
20021
20048
|
this.settings.set("lc_time", "C");
|
|
20022
20049
|
this.settings.set("default_transaction_isolation", "read committed");
|
|
20050
|
+
this.settings.set("lock_timeout", "0");
|
|
20051
|
+
this.settings.set("idle_in_transaction_session_timeout", "0");
|
|
20052
|
+
this.settings.set("transaction_timeout", "0");
|
|
20023
20053
|
this.settings.set("statement_timeout", "0");
|
|
20054
|
+
this.settings.set("check_function_bodies", "on");
|
|
20055
|
+
this.settings.set("xmloption", "content");
|
|
20056
|
+
this.settings.set("row_security", "on");
|
|
20024
20057
|
this.settings.set("array_nulls", "on");
|
|
20025
20058
|
this.settings.set("backslash_quote", "safe_encoding");
|
|
20026
20059
|
}
|
|
@@ -20310,6 +20343,11 @@ var MAX_IDENT = 63;
|
|
|
20310
20343
|
function truncIdent(s) {
|
|
20311
20344
|
return s.length > MAX_IDENT ? s.slice(0, MAX_IDENT) : s;
|
|
20312
20345
|
}
|
|
20346
|
+
function identitySequenceTarget(env, tableSchema, defaultName, options) {
|
|
20347
|
+
const parts = options.sequenceName;
|
|
20348
|
+
if (!parts || parts.length === 0) return { schema: tableSchema, name: defaultName };
|
|
20349
|
+
return targetSchema(env, parts);
|
|
20350
|
+
}
|
|
20313
20351
|
var SEQ_LIMITS = {
|
|
20314
20352
|
int2: { min: -32768n, max: 32767n },
|
|
20315
20353
|
int4: { min: -2147483648n, max: 2147483647n },
|
|
@@ -20486,8 +20524,8 @@ function buildColumn(env, schema, tableName, def, out, taken) {
|
|
|
20486
20524
|
break;
|
|
20487
20525
|
}
|
|
20488
20526
|
case "generated_identity": {
|
|
20489
|
-
const
|
|
20490
|
-
const seq = buildSequence(env, schema,
|
|
20527
|
+
const target = identitySequenceTarget(env, schema, truncIdent(`${tableName}_${def.name}_seq`), c.options);
|
|
20528
|
+
const seq = buildSequence(env, target.schema, target.name, c.options, false);
|
|
20491
20529
|
if (!c.options.as) {
|
|
20492
20530
|
seq.dataType = col.type.id === "int2" || col.type.id === "int4" || col.type.id === "int8" ? col.type.id : "int8";
|
|
20493
20531
|
const limits = SEQ_LIMITS[seq.dataType];
|
|
@@ -20496,7 +20534,7 @@ function buildColumn(env, schema, tableName, def, out, taken) {
|
|
|
20496
20534
|
}
|
|
20497
20535
|
seq.ownedBy = { table: tableName, column: def.name };
|
|
20498
20536
|
out.sequences.push(seq);
|
|
20499
|
-
col.identity = { always: c.always, sequence: `${schema.name}.${
|
|
20537
|
+
col.identity = { always: c.always, sequence: `${target.schema.name}.${target.name}` };
|
|
20500
20538
|
col.notNull = true;
|
|
20501
20539
|
break;
|
|
20502
20540
|
}
|
|
@@ -20632,10 +20670,11 @@ function executeCreateTable(env, stmt) {
|
|
|
20632
20670
|
throw pgError("invalid_table_definition", `multiple primary keys for table "${name}" are not allowed`, "42P16");
|
|
20633
20671
|
}
|
|
20634
20672
|
for (const seq of built.sequences) {
|
|
20635
|
-
|
|
20673
|
+
const seqSchema = state.getSchema(seq.schema);
|
|
20674
|
+
if (seqSchema.hasRelation(seq.name)) {
|
|
20636
20675
|
throw pgError("duplicate_table", `relation "${seq.name}" already exists`, "42P07");
|
|
20637
20676
|
}
|
|
20638
|
-
|
|
20677
|
+
seqSchema.sequences.set(seq.name, seq);
|
|
20639
20678
|
}
|
|
20640
20679
|
const table = new TableData(schema.name, name, built.columns, state.nextOid(), stmt.temp);
|
|
20641
20680
|
table.constraints = built.constraints;
|
|
@@ -20987,7 +21026,13 @@ function executeAlterTable(env, stmt) {
|
|
|
20987
21026
|
const built = { columns: [], constraints: [], sequences: [] };
|
|
20988
21027
|
const taken = constraintNames(table);
|
|
20989
21028
|
const col = buildColumn(env, schema, table.name, action.column, built, taken);
|
|
20990
|
-
for (const seq of built.sequences)
|
|
21029
|
+
for (const seq of built.sequences) {
|
|
21030
|
+
const seqSchema = state.getSchema(seq.schema);
|
|
21031
|
+
if (seqSchema.hasRelation(seq.name)) {
|
|
21032
|
+
throw pgError("duplicate_table", `relation "${seq.name}" already exists`, "42P07");
|
|
21033
|
+
}
|
|
21034
|
+
seqSchema.sequences.set(seq.name, seq);
|
|
21035
|
+
}
|
|
20991
21036
|
table.columns.push(col);
|
|
20992
21037
|
table.constraints.push(...built.constraints);
|
|
20993
21038
|
for (let i = 0; i < rows.length; i++) {
|
|
@@ -21307,12 +21352,32 @@ function executeAlterTable(env, stmt) {
|
|
|
21307
21352
|
"42P16"
|
|
21308
21353
|
);
|
|
21309
21354
|
}
|
|
21310
|
-
|
|
21311
|
-
|
|
21355
|
+
if (!col.notNull) {
|
|
21356
|
+
throw pgError(
|
|
21357
|
+
"object_not_in_prerequisite_state",
|
|
21358
|
+
`column "${action.column}" of relation "${table.name}" must be declared NOT NULL before identity can be added`,
|
|
21359
|
+
"55000"
|
|
21360
|
+
);
|
|
21361
|
+
}
|
|
21362
|
+
const target = identitySequenceTarget(
|
|
21363
|
+
env,
|
|
21364
|
+
schema,
|
|
21365
|
+
truncIdent(`${table.name}_${action.column}_seq`),
|
|
21366
|
+
action.options
|
|
21367
|
+
);
|
|
21368
|
+
if (target.schema.hasRelation(target.name)) {
|
|
21369
|
+
throw pgError("duplicate_table", `relation "${target.name}" already exists`, "42P07");
|
|
21370
|
+
}
|
|
21371
|
+
const seq = buildSequence(env, target.schema, target.name, action.options, false);
|
|
21372
|
+
if (!action.options.as) {
|
|
21373
|
+
seq.dataType = col.type.id === "int2" || col.type.id === "int4" || col.type.id === "int8" ? col.type.id : "int8";
|
|
21374
|
+
const limits = SEQ_LIMITS[seq.dataType];
|
|
21375
|
+
if (action.options.maxValue === void 0) seq.maxValue = seq.increment > 0n ? limits.max : -1n;
|
|
21376
|
+
if (action.options.minValue === void 0) seq.minValue = seq.increment > 0n ? 1n : limits.min;
|
|
21377
|
+
}
|
|
21312
21378
|
seq.ownedBy = { table: table.name, column: action.column };
|
|
21313
|
-
schema.sequences.set(
|
|
21314
|
-
col.identity = { always:
|
|
21315
|
-
col.notNull = true;
|
|
21379
|
+
target.schema.sequences.set(target.name, seq);
|
|
21380
|
+
col.identity = { always: action.always, sequence: `${target.schema.name}.${target.name}` };
|
|
21316
21381
|
break;
|
|
21317
21382
|
}
|
|
21318
21383
|
case "drop_identity": {
|