@crvouga/postgres-mem 0.1.0 → 1.0.1
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/unstable.js
CHANGED
|
@@ -2361,6 +2361,36 @@ var TYPE_OIDS = {
|
|
|
2361
2361
|
void: 2278,
|
|
2362
2362
|
unknown: 705
|
|
2363
2363
|
};
|
|
2364
|
+
var ARRAY_OIDS = {
|
|
2365
|
+
bool: 1e3,
|
|
2366
|
+
bytea: 1001,
|
|
2367
|
+
name: 1003,
|
|
2368
|
+
int8: 1016,
|
|
2369
|
+
int2: 1005,
|
|
2370
|
+
int4: 1007,
|
|
2371
|
+
text: 1009,
|
|
2372
|
+
oid: 1028,
|
|
2373
|
+
json: 199,
|
|
2374
|
+
float4: 1021,
|
|
2375
|
+
float8: 1022,
|
|
2376
|
+
money: 791,
|
|
2377
|
+
bpchar: 1014,
|
|
2378
|
+
varchar: 1015,
|
|
2379
|
+
date: 1182,
|
|
2380
|
+
time: 1183,
|
|
2381
|
+
timestamp: 1115,
|
|
2382
|
+
timestamptz: 1185,
|
|
2383
|
+
interval: 1187,
|
|
2384
|
+
timetz: 1270,
|
|
2385
|
+
numeric: 1231,
|
|
2386
|
+
record: 2287,
|
|
2387
|
+
uuid: 2951,
|
|
2388
|
+
jsonb: 3807
|
|
2389
|
+
};
|
|
2390
|
+
function typeOid(t) {
|
|
2391
|
+
if (isArrayType(t)) return ARRAY_OIDS[arrayElemType(t)] ?? 2277;
|
|
2392
|
+
return TYPE_OIDS[t] ?? 705;
|
|
2393
|
+
}
|
|
2364
2394
|
function shortestParts(v) {
|
|
2365
2395
|
const s = Math.abs(v).toString();
|
|
2366
2396
|
if (s.includes("e") || s.includes("E")) {
|
|
@@ -4451,6 +4481,9 @@ var FACTORIES = /* @__PURE__ */ new Map([
|
|
|
4451
4481
|
["regr_syy", () => new CorrAcc("regr_syy")],
|
|
4452
4482
|
["regr_sxy", () => new CorrAcc("regr_sxy")]
|
|
4453
4483
|
]);
|
|
4484
|
+
function getAggregateFactories() {
|
|
4485
|
+
return FACTORIES;
|
|
4486
|
+
}
|
|
4454
4487
|
function isAggregateName(name) {
|
|
4455
4488
|
return FACTORIES.has(name);
|
|
4456
4489
|
}
|
|
@@ -8275,6 +8308,9 @@ function isWindowFunctionName(name) {
|
|
|
8275
8308
|
|
|
8276
8309
|
// src/schema/catalog.ts
|
|
8277
8310
|
var builder = null;
|
|
8311
|
+
function setCatalogBuilder(b) {
|
|
8312
|
+
builder = b;
|
|
8313
|
+
}
|
|
8278
8314
|
function catalogRelation(ctx, schema, name) {
|
|
8279
8315
|
if (schema !== "pg_catalog" && schema !== "information_schema") return null;
|
|
8280
8316
|
return builder ? builder(ctx, schema, name) : null;
|
|
@@ -8301,6 +8337,842 @@ var PG_CATALOG_RELATIONS = /* @__PURE__ */ new Set([
|
|
|
8301
8337
|
"pg_trigger"
|
|
8302
8338
|
]);
|
|
8303
8339
|
|
|
8340
|
+
// src/schema/catalog-tables.ts
|
|
8341
|
+
function rel(specs, rows, table) {
|
|
8342
|
+
const columns = specs.map(([name, type]) => ({ name, type, table }));
|
|
8343
|
+
return { columns, rows };
|
|
8344
|
+
}
|
|
8345
|
+
var OWNER = "postgres";
|
|
8346
|
+
function* allTables(state) {
|
|
8347
|
+
for (const schema of state.schemas.values()) {
|
|
8348
|
+
for (const t of schema.tables.values()) yield t;
|
|
8349
|
+
}
|
|
8350
|
+
}
|
|
8351
|
+
function* allSequences(state) {
|
|
8352
|
+
for (const schema of state.schemas.values()) {
|
|
8353
|
+
for (const s of schema.sequences.values()) yield s;
|
|
8354
|
+
}
|
|
8355
|
+
}
|
|
8356
|
+
var NS_PG_CATALOG = 11;
|
|
8357
|
+
var NS_INFORMATION_SCHEMA = 13212;
|
|
8358
|
+
function namespaceOid(state, name) {
|
|
8359
|
+
if (name === "pg_catalog") return NS_PG_CATALOG;
|
|
8360
|
+
if (name === "information_schema") return NS_INFORMATION_SCHEMA;
|
|
8361
|
+
return state.schemas.get(name)?.oid ?? 0;
|
|
8362
|
+
}
|
|
8363
|
+
function attTypmod(mod, type) {
|
|
8364
|
+
if (!mod || mod.a === void 0) return -1;
|
|
8365
|
+
if (type === "numeric") return (mod.a << 16 | (mod.b ?? 0)) + 4;
|
|
8366
|
+
if (type === "varchar" || type === "bpchar") return mod.a + 4;
|
|
8367
|
+
return mod.a;
|
|
8368
|
+
}
|
|
8369
|
+
function enumOid(ctx, t) {
|
|
8370
|
+
if (!isEnumType(t)) return typeOid(t);
|
|
8371
|
+
const e = ctx.state.findEnumByKey(t.slice(5));
|
|
8372
|
+
return e ? e.oid : 0;
|
|
8373
|
+
}
|
|
8374
|
+
function pgNamespace(state) {
|
|
8375
|
+
const rows = [
|
|
8376
|
+
[NS_PG_CATALOG, "pg_catalog", 10, null],
|
|
8377
|
+
[NS_INFORMATION_SCHEMA, "information_schema", 10, null]
|
|
8378
|
+
];
|
|
8379
|
+
for (const s of state.schemas.values()) rows.push([s.oid, s.name, 10, null]);
|
|
8380
|
+
return rel(
|
|
8381
|
+
[
|
|
8382
|
+
["oid", "oid"],
|
|
8383
|
+
["nspname", "name"],
|
|
8384
|
+
["nspowner", "oid"],
|
|
8385
|
+
["nspacl", "text[]"]
|
|
8386
|
+
],
|
|
8387
|
+
rows,
|
|
8388
|
+
"pg_namespace"
|
|
8389
|
+
);
|
|
8390
|
+
}
|
|
8391
|
+
function pgClass(ctx) {
|
|
8392
|
+
const state = ctx.state;
|
|
8393
|
+
const rows = [];
|
|
8394
|
+
const push = (oid, name, schema, kind, natts, tuples, hasindex, populated, temp) => {
|
|
8395
|
+
rows.push([
|
|
8396
|
+
oid,
|
|
8397
|
+
name,
|
|
8398
|
+
namespaceOid(state, schema),
|
|
8399
|
+
0,
|
|
8400
|
+
10,
|
|
8401
|
+
kind === "i" ? 403 : kind === "S" || kind === "v" ? 0 : 2,
|
|
8402
|
+
oid,
|
|
8403
|
+
0,
|
|
8404
|
+
0,
|
|
8405
|
+
tuples,
|
|
8406
|
+
0,
|
|
8407
|
+
0,
|
|
8408
|
+
hasindex,
|
|
8409
|
+
false,
|
|
8410
|
+
temp ? "t" : "p",
|
|
8411
|
+
kind,
|
|
8412
|
+
natts,
|
|
8413
|
+
0,
|
|
8414
|
+
false,
|
|
8415
|
+
false,
|
|
8416
|
+
false,
|
|
8417
|
+
false,
|
|
8418
|
+
false,
|
|
8419
|
+
populated,
|
|
8420
|
+
kind === "r" ? "d" : "n",
|
|
8421
|
+
false,
|
|
8422
|
+
0,
|
|
8423
|
+
null,
|
|
8424
|
+
null,
|
|
8425
|
+
null
|
|
8426
|
+
]);
|
|
8427
|
+
};
|
|
8428
|
+
for (const schemaData of state.schemas.values()) {
|
|
8429
|
+
for (const t of schemaData.tables.values()) {
|
|
8430
|
+
const hasIndex = t.constraints.some((c) => c.kind === "primary_key" || c.kind === "unique") || [...schemaData.indexes.values()].some((i) => i.table === t.name);
|
|
8431
|
+
push(t.oid, t.name, t.schema, "r", t.columns.length, t.rows.length, hasIndex, true, t.temp);
|
|
8432
|
+
}
|
|
8433
|
+
for (const v of schemaData.views.values()) {
|
|
8434
|
+
push(
|
|
8435
|
+
v.oid,
|
|
8436
|
+
v.name,
|
|
8437
|
+
v.schema,
|
|
8438
|
+
v.materialized ? "m" : "v",
|
|
8439
|
+
v.columns?.length ?? 0,
|
|
8440
|
+
v.matRows?.length ?? 0,
|
|
8441
|
+
false,
|
|
8442
|
+
!v.materialized || v.matRows !== null,
|
|
8443
|
+
v.temp
|
|
8444
|
+
);
|
|
8445
|
+
}
|
|
8446
|
+
for (const s of schemaData.sequences.values()) push(s.oid, s.name, s.schema, "S", 3, 1, false, true, s.temp);
|
|
8447
|
+
for (const i of schemaData.indexes.values()) {
|
|
8448
|
+
push(
|
|
8449
|
+
state.schemas.get(i.schema)?.tables.get(i.table)?.oid ?? 0,
|
|
8450
|
+
i.name,
|
|
8451
|
+
i.schema,
|
|
8452
|
+
"i",
|
|
8453
|
+
i.columns.length,
|
|
8454
|
+
0,
|
|
8455
|
+
false,
|
|
8456
|
+
true,
|
|
8457
|
+
false
|
|
8458
|
+
);
|
|
8459
|
+
}
|
|
8460
|
+
}
|
|
8461
|
+
return rel(
|
|
8462
|
+
[
|
|
8463
|
+
["oid", "oid"],
|
|
8464
|
+
["relname", "name"],
|
|
8465
|
+
["relnamespace", "oid"],
|
|
8466
|
+
["reltype", "oid"],
|
|
8467
|
+
["relowner", "oid"],
|
|
8468
|
+
["relam", "oid"],
|
|
8469
|
+
["relfilenode", "oid"],
|
|
8470
|
+
["reltablespace", "oid"],
|
|
8471
|
+
["relpages", "int4"],
|
|
8472
|
+
["reltuples", "float4"],
|
|
8473
|
+
["relallvisible", "int4"],
|
|
8474
|
+
["reltoastrelid", "oid"],
|
|
8475
|
+
["relhasindex", "bool"],
|
|
8476
|
+
["relisshared", "bool"],
|
|
8477
|
+
["relpersistence", "bpchar"],
|
|
8478
|
+
["relkind", "bpchar"],
|
|
8479
|
+
["relnatts", "int2"],
|
|
8480
|
+
["relchecks", "int2"],
|
|
8481
|
+
["relhasrules", "bool"],
|
|
8482
|
+
["relhastriggers", "bool"],
|
|
8483
|
+
["relhassubclass", "bool"],
|
|
8484
|
+
["relrowsecurity", "bool"],
|
|
8485
|
+
["relforcerowsecurity", "bool"],
|
|
8486
|
+
["relispopulated", "bool"],
|
|
8487
|
+
["relreplident", "bpchar"],
|
|
8488
|
+
["relispartition", "bool"],
|
|
8489
|
+
["relrewrite", "oid"],
|
|
8490
|
+
["relacl", "text[]"],
|
|
8491
|
+
["reloptions", "text[]"],
|
|
8492
|
+
["relpartbound", "text"]
|
|
8493
|
+
],
|
|
8494
|
+
rows,
|
|
8495
|
+
"pg_class"
|
|
8496
|
+
);
|
|
8497
|
+
}
|
|
8498
|
+
function pgAttribute(ctx) {
|
|
8499
|
+
const rows = [];
|
|
8500
|
+
for (const t of allTables(ctx.state)) {
|
|
8501
|
+
t.columns.forEach((c, i) => {
|
|
8502
|
+
rows.push([
|
|
8503
|
+
t.oid,
|
|
8504
|
+
c.name,
|
|
8505
|
+
enumOid(ctx, c.type.id),
|
|
8506
|
+
i + 1,
|
|
8507
|
+
attTypmod(c.type.mod, c.type.id),
|
|
8508
|
+
-1,
|
|
8509
|
+
c.notNull,
|
|
8510
|
+
c.defaultExpr !== null || c.identity !== null,
|
|
8511
|
+
false,
|
|
8512
|
+
c.identity ? c.identity.always ? "a" : "d" : "",
|
|
8513
|
+
c.generated ? "s" : "",
|
|
8514
|
+
isArrayType(c.type.id) ? 1 : 0
|
|
8515
|
+
]);
|
|
8516
|
+
});
|
|
8517
|
+
}
|
|
8518
|
+
return rel(
|
|
8519
|
+
[
|
|
8520
|
+
["attrelid", "oid"],
|
|
8521
|
+
["attname", "name"],
|
|
8522
|
+
["atttypid", "oid"],
|
|
8523
|
+
["attnum", "int2"],
|
|
8524
|
+
["atttypmod", "int4"],
|
|
8525
|
+
["attlen", "int2"],
|
|
8526
|
+
["attnotnull", "bool"],
|
|
8527
|
+
["atthasdef", "bool"],
|
|
8528
|
+
["attisdropped", "bool"],
|
|
8529
|
+
["attidentity", "bpchar"],
|
|
8530
|
+
["attgenerated", "bpchar"],
|
|
8531
|
+
["attndims", "int2"]
|
|
8532
|
+
],
|
|
8533
|
+
rows,
|
|
8534
|
+
"pg_attribute"
|
|
8535
|
+
);
|
|
8536
|
+
}
|
|
8537
|
+
function pgType(ctx) {
|
|
8538
|
+
const rows = [];
|
|
8539
|
+
for (const [name, oid] of Object.entries(TYPE_OIDS)) {
|
|
8540
|
+
const isArr = name.startsWith("_");
|
|
8541
|
+
rows.push([
|
|
8542
|
+
oid,
|
|
8543
|
+
name,
|
|
8544
|
+
NS_PG_CATALOG,
|
|
8545
|
+
"b",
|
|
8546
|
+
isArr ? "A" : "U",
|
|
8547
|
+
isArr ? TYPE_OIDS[name.slice(1)] ?? 0 : 0,
|
|
8548
|
+
isArr ? 0 : TYPE_OIDS[`_${name}`] ?? 0,
|
|
8549
|
+
0,
|
|
8550
|
+
0,
|
|
8551
|
+
-1
|
|
8552
|
+
]);
|
|
8553
|
+
}
|
|
8554
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8555
|
+
for (const e of schema.enums.values()) {
|
|
8556
|
+
rows.push([e.oid, e.name, namespaceOid(ctx.state, e.schema), "e", "E", 0, 0, 0, 0, 4]);
|
|
8557
|
+
}
|
|
8558
|
+
for (const d of schema.domains.values()) {
|
|
8559
|
+
rows.push([d.oid, d.name, namespaceOid(ctx.state, d.schema), "d", "S", 0, 0, typeOid(d.baseType.id), 0, -1]);
|
|
8560
|
+
}
|
|
8561
|
+
}
|
|
8562
|
+
return rel(
|
|
8563
|
+
[
|
|
8564
|
+
["oid", "oid"],
|
|
8565
|
+
["typname", "name"],
|
|
8566
|
+
["typnamespace", "oid"],
|
|
8567
|
+
["typtype", "bpchar"],
|
|
8568
|
+
["typcategory", "bpchar"],
|
|
8569
|
+
["typelem", "oid"],
|
|
8570
|
+
["typarray", "oid"],
|
|
8571
|
+
["typbasetype", "oid"],
|
|
8572
|
+
["typrelid", "oid"],
|
|
8573
|
+
["typlen", "int2"]
|
|
8574
|
+
],
|
|
8575
|
+
rows,
|
|
8576
|
+
"pg_type"
|
|
8577
|
+
);
|
|
8578
|
+
}
|
|
8579
|
+
function pgProc(ctx) {
|
|
8580
|
+
const rows = [];
|
|
8581
|
+
let oid = 1e3;
|
|
8582
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8583
|
+
const push = (name, ns, kind, retset, nargs, realOid) => {
|
|
8584
|
+
rows.push([realOid ?? oid++, name, ns, kind, retset, nargs]);
|
|
8585
|
+
};
|
|
8586
|
+
for (const name of getScalarFunctions().keys()) {
|
|
8587
|
+
if (!seen.has(name)) {
|
|
8588
|
+
seen.add(name);
|
|
8589
|
+
push(name, NS_PG_CATALOG, "f", false, -1);
|
|
8590
|
+
}
|
|
8591
|
+
}
|
|
8592
|
+
for (const name of Object.keys(getAggregateFactories())) {
|
|
8593
|
+
if (!seen.has(`agg:${name}`)) {
|
|
8594
|
+
seen.add(`agg:${name}`);
|
|
8595
|
+
push(name, NS_PG_CATALOG, "a", false, -1);
|
|
8596
|
+
}
|
|
8597
|
+
}
|
|
8598
|
+
for (const name of WINDOW_FUNCTION_NAMES) push(name, NS_PG_CATALOG, "w", false, -1);
|
|
8599
|
+
for (const name of getSrfFunctions().keys()) push(name, NS_PG_CATALOG, "f", true, -1);
|
|
8600
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8601
|
+
for (const fns of schema.functions.values()) {
|
|
8602
|
+
for (const f of fns) {
|
|
8603
|
+
push(f.name, namespaceOid(ctx.state, f.schema), "f", f.returnsSet, f.argTypes.length, f.oid);
|
|
8604
|
+
}
|
|
8605
|
+
}
|
|
8606
|
+
}
|
|
8607
|
+
return rel(
|
|
8608
|
+
[
|
|
8609
|
+
["oid", "oid"],
|
|
8610
|
+
["proname", "name"],
|
|
8611
|
+
["pronamespace", "oid"],
|
|
8612
|
+
["prokind", "bpchar"],
|
|
8613
|
+
["proretset", "bool"],
|
|
8614
|
+
["pronargs", "int2"]
|
|
8615
|
+
],
|
|
8616
|
+
rows,
|
|
8617
|
+
"pg_proc"
|
|
8618
|
+
);
|
|
8619
|
+
}
|
|
8620
|
+
function pgEnum(ctx) {
|
|
8621
|
+
const rows = [];
|
|
8622
|
+
let oid = 2e4;
|
|
8623
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8624
|
+
for (const e of schema.enums.values()) {
|
|
8625
|
+
e.labels.forEach((label, i) => {
|
|
8626
|
+
rows.push([oid++, e.oid, i + 1, label]);
|
|
8627
|
+
});
|
|
8628
|
+
}
|
|
8629
|
+
}
|
|
8630
|
+
return rel(
|
|
8631
|
+
[
|
|
8632
|
+
["oid", "oid"],
|
|
8633
|
+
["enumtypid", "oid"],
|
|
8634
|
+
["enumsortorder", "float4"],
|
|
8635
|
+
["enumlabel", "name"]
|
|
8636
|
+
],
|
|
8637
|
+
rows,
|
|
8638
|
+
"pg_enum"
|
|
8639
|
+
);
|
|
8640
|
+
}
|
|
8641
|
+
function pgConstraint(ctx) {
|
|
8642
|
+
const rows = [];
|
|
8643
|
+
let oid = 3e4;
|
|
8644
|
+
for (const t of allTables(ctx.state)) {
|
|
8645
|
+
for (const c of t.constraints) {
|
|
8646
|
+
const contype = c.kind === "primary_key" ? "p" : c.kind === "unique" ? "u" : c.kind === "check" ? "c" : "f";
|
|
8647
|
+
const refTable = c.kind === "foreign_key" ? ctx.state.schemas.get(c.refSchema)?.tables.get(c.refTable) : void 0;
|
|
8648
|
+
rows.push([oid++, c.name, namespaceOid(ctx.state, t.schema), contype, false, false, t.oid, refTable?.oid ?? 0]);
|
|
8649
|
+
}
|
|
8650
|
+
for (const col of t.columns) {
|
|
8651
|
+
if (col.notNull) {
|
|
8652
|
+
rows.push([
|
|
8653
|
+
oid++,
|
|
8654
|
+
`${t.name}_${col.name}_not_null`,
|
|
8655
|
+
namespaceOid(ctx.state, t.schema),
|
|
8656
|
+
"n",
|
|
8657
|
+
false,
|
|
8658
|
+
false,
|
|
8659
|
+
t.oid,
|
|
8660
|
+
0
|
|
8661
|
+
]);
|
|
8662
|
+
}
|
|
8663
|
+
}
|
|
8664
|
+
}
|
|
8665
|
+
return rel(
|
|
8666
|
+
[
|
|
8667
|
+
["oid", "oid"],
|
|
8668
|
+
["conname", "name"],
|
|
8669
|
+
["connamespace", "oid"],
|
|
8670
|
+
["contype", "bpchar"],
|
|
8671
|
+
["condeferrable", "bool"],
|
|
8672
|
+
["condeferred", "bool"],
|
|
8673
|
+
["conrelid", "oid"],
|
|
8674
|
+
["confrelid", "oid"]
|
|
8675
|
+
],
|
|
8676
|
+
rows,
|
|
8677
|
+
"pg_constraint"
|
|
8678
|
+
);
|
|
8679
|
+
}
|
|
8680
|
+
function pgIndex(ctx) {
|
|
8681
|
+
const rows = [];
|
|
8682
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8683
|
+
for (const i of schema.indexes.values()) {
|
|
8684
|
+
const table = schema.tables.get(i.table);
|
|
8685
|
+
const isPrimary = i.isConstraint && table?.constraints.some((c) => c.kind === "primary_key" && c.name === i.name) === true;
|
|
8686
|
+
rows.push([table?.oid ?? 0, table?.oid ?? 0, i.columns.length, i.unique, isPrimary, i.where !== null]);
|
|
8687
|
+
}
|
|
8688
|
+
}
|
|
8689
|
+
return rel(
|
|
8690
|
+
[
|
|
8691
|
+
["indexrelid", "oid"],
|
|
8692
|
+
["indrelid", "oid"],
|
|
8693
|
+
["indnatts", "int2"],
|
|
8694
|
+
["indisunique", "bool"],
|
|
8695
|
+
["indisprimary", "bool"],
|
|
8696
|
+
["indpred", "bool"]
|
|
8697
|
+
],
|
|
8698
|
+
rows,
|
|
8699
|
+
"pg_index"
|
|
8700
|
+
);
|
|
8701
|
+
}
|
|
8702
|
+
function pgSequence(ctx) {
|
|
8703
|
+
const rows = [];
|
|
8704
|
+
for (const s of allSequences(ctx.state)) {
|
|
8705
|
+
rows.push([s.oid, typeOid(s.dataType), s.startValue, s.increment, s.maxValue, s.minValue, s.cache, s.cycle]);
|
|
8706
|
+
}
|
|
8707
|
+
return rel(
|
|
8708
|
+
[
|
|
8709
|
+
["seqrelid", "oid"],
|
|
8710
|
+
["seqtypid", "oid"],
|
|
8711
|
+
["seqstart", "int8"],
|
|
8712
|
+
["seqincrement", "int8"],
|
|
8713
|
+
["seqmax", "int8"],
|
|
8714
|
+
["seqmin", "int8"],
|
|
8715
|
+
["seqcache", "int8"],
|
|
8716
|
+
["seqcycle", "bool"]
|
|
8717
|
+
],
|
|
8718
|
+
rows,
|
|
8719
|
+
"pg_sequence"
|
|
8720
|
+
);
|
|
8721
|
+
}
|
|
8722
|
+
function pgSequencesView(ctx) {
|
|
8723
|
+
const rows = [];
|
|
8724
|
+
for (const s of allSequences(ctx.state)) {
|
|
8725
|
+
rows.push([
|
|
8726
|
+
s.schema,
|
|
8727
|
+
s.name,
|
|
8728
|
+
OWNER,
|
|
8729
|
+
typeDisplayName(s.dataType),
|
|
8730
|
+
s.startValue,
|
|
8731
|
+
s.minValue,
|
|
8732
|
+
s.maxValue,
|
|
8733
|
+
s.increment,
|
|
8734
|
+
s.cycle,
|
|
8735
|
+
s.cache,
|
|
8736
|
+
s.isCalled ? s.lastValue : null
|
|
8737
|
+
]);
|
|
8738
|
+
}
|
|
8739
|
+
return rel(
|
|
8740
|
+
[
|
|
8741
|
+
["schemaname", "name"],
|
|
8742
|
+
["sequencename", "name"],
|
|
8743
|
+
["sequenceowner", "name"],
|
|
8744
|
+
["data_type", "text"],
|
|
8745
|
+
["start_value", "int8"],
|
|
8746
|
+
["min_value", "int8"],
|
|
8747
|
+
["max_value", "int8"],
|
|
8748
|
+
["increment_by", "int8"],
|
|
8749
|
+
["cycle", "bool"],
|
|
8750
|
+
["cache_size", "int8"],
|
|
8751
|
+
["last_value", "int8"]
|
|
8752
|
+
],
|
|
8753
|
+
rows,
|
|
8754
|
+
"pg_sequences"
|
|
8755
|
+
);
|
|
8756
|
+
}
|
|
8757
|
+
function pgTables(ctx) {
|
|
8758
|
+
const rows = [];
|
|
8759
|
+
for (const t of allTables(ctx.state)) {
|
|
8760
|
+
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);
|
|
8761
|
+
rows.push([t.schema, t.name, OWNER, null, hasIndexes, false, t.triggers.length > 0, false]);
|
|
8762
|
+
}
|
|
8763
|
+
return rel(
|
|
8764
|
+
[
|
|
8765
|
+
["schemaname", "name"],
|
|
8766
|
+
["tablename", "name"],
|
|
8767
|
+
["tableowner", "name"],
|
|
8768
|
+
["tablespace", "name"],
|
|
8769
|
+
["hasindexes", "bool"],
|
|
8770
|
+
["hasrules", "bool"],
|
|
8771
|
+
["hastriggers", "bool"],
|
|
8772
|
+
["rowsecurity", "bool"]
|
|
8773
|
+
],
|
|
8774
|
+
rows,
|
|
8775
|
+
"pg_tables"
|
|
8776
|
+
);
|
|
8777
|
+
}
|
|
8778
|
+
function pgViews(ctx, materialized) {
|
|
8779
|
+
const rows = [];
|
|
8780
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8781
|
+
for (const v of schema.views.values()) {
|
|
8782
|
+
if (v.materialized !== materialized) continue;
|
|
8783
|
+
if (materialized) rows.push([v.schema, v.name, OWNER, null, v.matRows !== null, null]);
|
|
8784
|
+
else rows.push([v.schema, v.name, OWNER, null]);
|
|
8785
|
+
}
|
|
8786
|
+
}
|
|
8787
|
+
if (materialized) {
|
|
8788
|
+
return rel(
|
|
8789
|
+
[
|
|
8790
|
+
["schemaname", "name"],
|
|
8791
|
+
["matviewname", "name"],
|
|
8792
|
+
["matviewowner", "name"],
|
|
8793
|
+
["tablespace", "name"],
|
|
8794
|
+
["ispopulated", "bool"],
|
|
8795
|
+
["definition", "text"]
|
|
8796
|
+
],
|
|
8797
|
+
rows,
|
|
8798
|
+
"pg_matviews"
|
|
8799
|
+
);
|
|
8800
|
+
}
|
|
8801
|
+
return rel(
|
|
8802
|
+
[
|
|
8803
|
+
["schemaname", "name"],
|
|
8804
|
+
["viewname", "name"],
|
|
8805
|
+
["viewowner", "name"],
|
|
8806
|
+
["definition", "text"]
|
|
8807
|
+
],
|
|
8808
|
+
rows,
|
|
8809
|
+
"pg_views"
|
|
8810
|
+
);
|
|
8811
|
+
}
|
|
8812
|
+
function pgIndexesView(ctx) {
|
|
8813
|
+
const rows = [];
|
|
8814
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8815
|
+
for (const i of schema.indexes.values()) {
|
|
8816
|
+
rows.push([i.schema, i.table, i.name, null, null]);
|
|
8817
|
+
}
|
|
8818
|
+
}
|
|
8819
|
+
return rel(
|
|
8820
|
+
[
|
|
8821
|
+
["schemaname", "name"],
|
|
8822
|
+
["tablename", "name"],
|
|
8823
|
+
["indexname", "name"],
|
|
8824
|
+
["tablespace", "name"],
|
|
8825
|
+
["indexdef", "text"]
|
|
8826
|
+
],
|
|
8827
|
+
rows,
|
|
8828
|
+
"pg_indexes"
|
|
8829
|
+
);
|
|
8830
|
+
}
|
|
8831
|
+
function pgSettings(ctx) {
|
|
8832
|
+
const rows = [];
|
|
8833
|
+
const keys = /* @__PURE__ */ new Set([...ctx.state.settings.keys(), ...ctx.state.localSettings.keys()]);
|
|
8834
|
+
for (const name of [...keys].sort()) {
|
|
8835
|
+
rows.push([name, ctx.state.getSetting(name) ?? null]);
|
|
8836
|
+
}
|
|
8837
|
+
return rel(
|
|
8838
|
+
[
|
|
8839
|
+
["name", "text"],
|
|
8840
|
+
["setting", "text"]
|
|
8841
|
+
],
|
|
8842
|
+
rows,
|
|
8843
|
+
"pg_settings"
|
|
8844
|
+
);
|
|
8845
|
+
}
|
|
8846
|
+
function pgDatabase() {
|
|
8847
|
+
return rel(
|
|
8848
|
+
[
|
|
8849
|
+
["oid", "oid"],
|
|
8850
|
+
["datname", "name"],
|
|
8851
|
+
["encoding", "int4"],
|
|
8852
|
+
["datistemplate", "bool"],
|
|
8853
|
+
["datallowconn", "bool"]
|
|
8854
|
+
],
|
|
8855
|
+
[[5, "postgres", 6, false, true]],
|
|
8856
|
+
"pg_database"
|
|
8857
|
+
);
|
|
8858
|
+
}
|
|
8859
|
+
function pgRoles() {
|
|
8860
|
+
return rel(
|
|
8861
|
+
[
|
|
8862
|
+
["oid", "oid"],
|
|
8863
|
+
["rolname", "name"],
|
|
8864
|
+
["rolsuper", "bool"],
|
|
8865
|
+
["rolcanlogin", "bool"]
|
|
8866
|
+
],
|
|
8867
|
+
[[10, OWNER, true, true]],
|
|
8868
|
+
"pg_roles"
|
|
8869
|
+
);
|
|
8870
|
+
}
|
|
8871
|
+
function pgTrigger(ctx) {
|
|
8872
|
+
const rows = [];
|
|
8873
|
+
let oid = 4e4;
|
|
8874
|
+
for (const t of allTables(ctx.state)) {
|
|
8875
|
+
for (const tr of t.triggers) {
|
|
8876
|
+
rows.push([oid++, tr.name, t.oid, !tr.forEachRow]);
|
|
8877
|
+
}
|
|
8878
|
+
}
|
|
8879
|
+
return rel(
|
|
8880
|
+
[
|
|
8881
|
+
["oid", "oid"],
|
|
8882
|
+
["tgname", "name"],
|
|
8883
|
+
["tgrelid", "oid"],
|
|
8884
|
+
["tgisinternal", "bool"]
|
|
8885
|
+
],
|
|
8886
|
+
rows,
|
|
8887
|
+
"pg_trigger"
|
|
8888
|
+
);
|
|
8889
|
+
}
|
|
8890
|
+
var CATALOG_NAME = "postgres";
|
|
8891
|
+
function infoSchemata(state) {
|
|
8892
|
+
const rows = [
|
|
8893
|
+
[CATALOG_NAME, "pg_catalog", OWNER],
|
|
8894
|
+
[CATALOG_NAME, "information_schema", OWNER]
|
|
8895
|
+
];
|
|
8896
|
+
for (const s of state.schemas.values()) rows.push([CATALOG_NAME, s.name, OWNER]);
|
|
8897
|
+
return rel(
|
|
8898
|
+
[
|
|
8899
|
+
["catalog_name", "name"],
|
|
8900
|
+
["schema_name", "name"],
|
|
8901
|
+
["schema_owner", "name"]
|
|
8902
|
+
],
|
|
8903
|
+
rows,
|
|
8904
|
+
"schemata"
|
|
8905
|
+
);
|
|
8906
|
+
}
|
|
8907
|
+
function infoTables(ctx) {
|
|
8908
|
+
const rows = [];
|
|
8909
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8910
|
+
for (const t of schema.tables.values()) {
|
|
8911
|
+
rows.push([CATALOG_NAME, t.schema, t.name, t.temp ? "LOCAL TEMPORARY" : "BASE TABLE", "YES"]);
|
|
8912
|
+
}
|
|
8913
|
+
for (const v of schema.views.values()) {
|
|
8914
|
+
if (!v.materialized) rows.push([CATALOG_NAME, v.schema, v.name, "VIEW", "NO"]);
|
|
8915
|
+
}
|
|
8916
|
+
}
|
|
8917
|
+
return rel(
|
|
8918
|
+
[
|
|
8919
|
+
["table_catalog", "name"],
|
|
8920
|
+
["table_schema", "name"],
|
|
8921
|
+
["table_name", "name"],
|
|
8922
|
+
["table_type", "text"],
|
|
8923
|
+
["is_insertable_into", "text"]
|
|
8924
|
+
],
|
|
8925
|
+
rows,
|
|
8926
|
+
"tables"
|
|
8927
|
+
);
|
|
8928
|
+
}
|
|
8929
|
+
function infoColumns(ctx) {
|
|
8930
|
+
const rows = [];
|
|
8931
|
+
for (const t of allTables(ctx.state)) {
|
|
8932
|
+
t.columns.forEach((c, i) => {
|
|
8933
|
+
const id = c.type.id;
|
|
8934
|
+
const isNumeric2 = id === "numeric";
|
|
8935
|
+
const isIntish = id === "int2" || id === "int4" || id === "int8";
|
|
8936
|
+
const charMax = (id === "varchar" || id === "bpchar") && c.type.mod?.a !== void 0 ? c.type.mod.a : null;
|
|
8937
|
+
const dataType = isArrayType(id) ? "ARRAY" : isEnumType(id) ? "USER-DEFINED" : typeDisplayName(id);
|
|
8938
|
+
const udt = isArrayType(id) ? `_${arrayUdt(id)}` : isEnumType(id) ? id.slice(5).split(".").pop() : id;
|
|
8939
|
+
rows.push([
|
|
8940
|
+
CATALOG_NAME,
|
|
8941
|
+
t.schema,
|
|
8942
|
+
t.name,
|
|
8943
|
+
c.name,
|
|
8944
|
+
i + 1,
|
|
8945
|
+
null,
|
|
8946
|
+
c.notNull ? "NO" : "YES",
|
|
8947
|
+
dataType,
|
|
8948
|
+
charMax,
|
|
8949
|
+
isNumeric2 ? c.type.mod?.a ?? null : isIntish ? id === "int2" ? 16 : id === "int4" ? 32 : 64 : null,
|
|
8950
|
+
isNumeric2 ? c.type.mod?.b ?? null : isIntish ? 0 : null,
|
|
8951
|
+
udt,
|
|
8952
|
+
c.identity ? "YES" : "NO",
|
|
8953
|
+
c.generated ? "ALWAYS" : "NEVER",
|
|
8954
|
+
"YES"
|
|
8955
|
+
]);
|
|
8956
|
+
});
|
|
8957
|
+
}
|
|
8958
|
+
return rel(
|
|
8959
|
+
[
|
|
8960
|
+
["table_catalog", "name"],
|
|
8961
|
+
["table_schema", "name"],
|
|
8962
|
+
["table_name", "name"],
|
|
8963
|
+
["column_name", "name"],
|
|
8964
|
+
["ordinal_position", "int4"],
|
|
8965
|
+
["column_default", "text"],
|
|
8966
|
+
["is_nullable", "text"],
|
|
8967
|
+
["data_type", "text"],
|
|
8968
|
+
["character_maximum_length", "int4"],
|
|
8969
|
+
["numeric_precision", "int4"],
|
|
8970
|
+
["numeric_scale", "int4"],
|
|
8971
|
+
["udt_name", "name"],
|
|
8972
|
+
["is_identity", "text"],
|
|
8973
|
+
["is_generated", "text"],
|
|
8974
|
+
["is_updatable", "text"]
|
|
8975
|
+
],
|
|
8976
|
+
rows,
|
|
8977
|
+
"columns"
|
|
8978
|
+
);
|
|
8979
|
+
}
|
|
8980
|
+
function arrayUdt(t) {
|
|
8981
|
+
const elem = t.slice(0, -2);
|
|
8982
|
+
return isEnumType(elem) ? elem.slice(5).split(".").pop() : elem;
|
|
8983
|
+
}
|
|
8984
|
+
function infoViews(ctx) {
|
|
8985
|
+
const rows = [];
|
|
8986
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
8987
|
+
for (const v of schema.views.values()) {
|
|
8988
|
+
if (!v.materialized) rows.push([CATALOG_NAME, v.schema, v.name, null]);
|
|
8989
|
+
}
|
|
8990
|
+
}
|
|
8991
|
+
return rel(
|
|
8992
|
+
[
|
|
8993
|
+
["table_catalog", "name"],
|
|
8994
|
+
["table_schema", "name"],
|
|
8995
|
+
["table_name", "name"],
|
|
8996
|
+
["view_definition", "text"]
|
|
8997
|
+
],
|
|
8998
|
+
rows,
|
|
8999
|
+
"views"
|
|
9000
|
+
);
|
|
9001
|
+
}
|
|
9002
|
+
function infoSequences(ctx) {
|
|
9003
|
+
const rows = [];
|
|
9004
|
+
for (const s of allSequences(ctx.state)) {
|
|
9005
|
+
rows.push([
|
|
9006
|
+
CATALOG_NAME,
|
|
9007
|
+
s.schema,
|
|
9008
|
+
s.name,
|
|
9009
|
+
typeDisplayName(s.dataType),
|
|
9010
|
+
String(s.startValue),
|
|
9011
|
+
String(s.minValue),
|
|
9012
|
+
String(s.maxValue),
|
|
9013
|
+
String(s.increment),
|
|
9014
|
+
s.cycle ? "YES" : "NO"
|
|
9015
|
+
]);
|
|
9016
|
+
}
|
|
9017
|
+
return rel(
|
|
9018
|
+
[
|
|
9019
|
+
["sequence_catalog", "name"],
|
|
9020
|
+
["sequence_schema", "name"],
|
|
9021
|
+
["sequence_name", "name"],
|
|
9022
|
+
["data_type", "text"],
|
|
9023
|
+
["start_value", "text"],
|
|
9024
|
+
["minimum_value", "text"],
|
|
9025
|
+
["maximum_value", "text"],
|
|
9026
|
+
["increment", "text"],
|
|
9027
|
+
["cycle_option", "text"]
|
|
9028
|
+
],
|
|
9029
|
+
rows,
|
|
9030
|
+
"sequences"
|
|
9031
|
+
);
|
|
9032
|
+
}
|
|
9033
|
+
function infoTableConstraints(ctx) {
|
|
9034
|
+
const rows = [];
|
|
9035
|
+
for (const t of allTables(ctx.state)) {
|
|
9036
|
+
for (const c of t.constraints) {
|
|
9037
|
+
const type = c.kind === "primary_key" ? "PRIMARY KEY" : c.kind === "unique" ? "UNIQUE" : c.kind === "check" ? "CHECK" : "FOREIGN KEY";
|
|
9038
|
+
rows.push([CATALOG_NAME, t.schema, c.name, CATALOG_NAME, t.schema, t.name, type]);
|
|
9039
|
+
}
|
|
9040
|
+
}
|
|
9041
|
+
return rel(
|
|
9042
|
+
[
|
|
9043
|
+
["constraint_catalog", "name"],
|
|
9044
|
+
["constraint_schema", "name"],
|
|
9045
|
+
["constraint_name", "name"],
|
|
9046
|
+
["table_catalog", "name"],
|
|
9047
|
+
["table_schema", "name"],
|
|
9048
|
+
["table_name", "name"],
|
|
9049
|
+
["constraint_type", "text"]
|
|
9050
|
+
],
|
|
9051
|
+
rows,
|
|
9052
|
+
"table_constraints"
|
|
9053
|
+
);
|
|
9054
|
+
}
|
|
9055
|
+
function infoKeyColumnUsage(ctx) {
|
|
9056
|
+
const rows = [];
|
|
9057
|
+
for (const t of allTables(ctx.state)) {
|
|
9058
|
+
for (const c of t.constraints) {
|
|
9059
|
+
if (c.kind !== "primary_key" && c.kind !== "unique" && c.kind !== "foreign_key") continue;
|
|
9060
|
+
c.columns.forEach((col, i) => {
|
|
9061
|
+
rows.push([CATALOG_NAME, t.schema, c.name, CATALOG_NAME, t.schema, t.name, col, i + 1]);
|
|
9062
|
+
});
|
|
9063
|
+
}
|
|
9064
|
+
}
|
|
9065
|
+
return rel(
|
|
9066
|
+
[
|
|
9067
|
+
["constraint_catalog", "name"],
|
|
9068
|
+
["constraint_schema", "name"],
|
|
9069
|
+
["constraint_name", "name"],
|
|
9070
|
+
["table_catalog", "name"],
|
|
9071
|
+
["table_schema", "name"],
|
|
9072
|
+
["table_name", "name"],
|
|
9073
|
+
["column_name", "name"],
|
|
9074
|
+
["ordinal_position", "int4"]
|
|
9075
|
+
],
|
|
9076
|
+
rows,
|
|
9077
|
+
"key_column_usage"
|
|
9078
|
+
);
|
|
9079
|
+
}
|
|
9080
|
+
function infoRoutines(ctx) {
|
|
9081
|
+
const rows = [];
|
|
9082
|
+
for (const schema of ctx.state.schemas.values()) {
|
|
9083
|
+
for (const fns of schema.functions.values()) {
|
|
9084
|
+
for (const f of fns) {
|
|
9085
|
+
rows.push([
|
|
9086
|
+
CATALOG_NAME,
|
|
9087
|
+
f.schema,
|
|
9088
|
+
f.name,
|
|
9089
|
+
"FUNCTION",
|
|
9090
|
+
f.returns ? typeDisplayName(f.returns) : null,
|
|
9091
|
+
f.language.toUpperCase()
|
|
9092
|
+
]);
|
|
9093
|
+
}
|
|
9094
|
+
}
|
|
9095
|
+
}
|
|
9096
|
+
return rel(
|
|
9097
|
+
[
|
|
9098
|
+
["routine_catalog", "name"],
|
|
9099
|
+
["routine_schema", "name"],
|
|
9100
|
+
["routine_name", "name"],
|
|
9101
|
+
["routine_type", "text"],
|
|
9102
|
+
["data_type", "text"],
|
|
9103
|
+
["external_language", "text"]
|
|
9104
|
+
],
|
|
9105
|
+
rows,
|
|
9106
|
+
"routines"
|
|
9107
|
+
);
|
|
9108
|
+
}
|
|
9109
|
+
function buildCatalogRelation(ctx, schema, name) {
|
|
9110
|
+
if (schema === "pg_catalog") {
|
|
9111
|
+
switch (name) {
|
|
9112
|
+
case "pg_namespace":
|
|
9113
|
+
return pgNamespace(ctx.state);
|
|
9114
|
+
case "pg_class":
|
|
9115
|
+
return pgClass(ctx);
|
|
9116
|
+
case "pg_attribute":
|
|
9117
|
+
return pgAttribute(ctx);
|
|
9118
|
+
case "pg_type":
|
|
9119
|
+
return pgType(ctx);
|
|
9120
|
+
case "pg_proc":
|
|
9121
|
+
return pgProc(ctx);
|
|
9122
|
+
case "pg_enum":
|
|
9123
|
+
return pgEnum(ctx);
|
|
9124
|
+
case "pg_constraint":
|
|
9125
|
+
return pgConstraint(ctx);
|
|
9126
|
+
case "pg_index":
|
|
9127
|
+
return pgIndex(ctx);
|
|
9128
|
+
case "pg_sequence":
|
|
9129
|
+
return pgSequence(ctx);
|
|
9130
|
+
case "pg_sequences":
|
|
9131
|
+
return pgSequencesView(ctx);
|
|
9132
|
+
case "pg_tables":
|
|
9133
|
+
return pgTables(ctx);
|
|
9134
|
+
case "pg_views":
|
|
9135
|
+
return pgViews(ctx, false);
|
|
9136
|
+
case "pg_matviews":
|
|
9137
|
+
return pgViews(ctx, true);
|
|
9138
|
+
case "pg_indexes":
|
|
9139
|
+
return pgIndexesView(ctx);
|
|
9140
|
+
case "pg_settings":
|
|
9141
|
+
return pgSettings(ctx);
|
|
9142
|
+
case "pg_database":
|
|
9143
|
+
return pgDatabase();
|
|
9144
|
+
case "pg_roles":
|
|
9145
|
+
case "pg_user":
|
|
9146
|
+
return pgRoles();
|
|
9147
|
+
case "pg_trigger":
|
|
9148
|
+
return pgTrigger(ctx);
|
|
9149
|
+
default:
|
|
9150
|
+
return null;
|
|
9151
|
+
}
|
|
9152
|
+
}
|
|
9153
|
+
switch (name) {
|
|
9154
|
+
case "schemata":
|
|
9155
|
+
return infoSchemata(ctx.state);
|
|
9156
|
+
case "tables":
|
|
9157
|
+
return infoTables(ctx);
|
|
9158
|
+
case "columns":
|
|
9159
|
+
return infoColumns(ctx);
|
|
9160
|
+
case "views":
|
|
9161
|
+
return infoViews(ctx);
|
|
9162
|
+
case "sequences":
|
|
9163
|
+
return infoSequences(ctx);
|
|
9164
|
+
case "table_constraints":
|
|
9165
|
+
return infoTableConstraints(ctx);
|
|
9166
|
+
case "key_column_usage":
|
|
9167
|
+
return infoKeyColumnUsage(ctx);
|
|
9168
|
+
case "routines":
|
|
9169
|
+
return infoRoutines(ctx);
|
|
9170
|
+
default:
|
|
9171
|
+
return null;
|
|
9172
|
+
}
|
|
9173
|
+
}
|
|
9174
|
+
setCatalogBuilder(buildCatalogRelation);
|
|
9175
|
+
|
|
8304
9176
|
// src/lexer/tokenize.ts
|
|
8305
9177
|
var IDENT_START = /[A-Za-z_\u0080-\uffff]/;
|
|
8306
9178
|
var IDENT_CONT = /[A-Za-z0-9_$\u0080-\uffff]/;
|
|
@@ -12352,13 +13224,13 @@ var RowScope = class {
|
|
|
12352
13224
|
function childEnv(env, outer) {
|
|
12353
13225
|
return { ctx: env.ctx, params: env.params, ctes: env.ctes, outer };
|
|
12354
13226
|
}
|
|
12355
|
-
function relationResult(
|
|
12356
|
-
const visible =
|
|
13227
|
+
function relationResult(rel2, command) {
|
|
13228
|
+
const visible = rel2.columns.map((c, i) => ({ i, c })).filter(({ c }) => !c.hidden);
|
|
12357
13229
|
return {
|
|
12358
13230
|
columns: visible.map(({ c }) => ({ name: c.name, type: c.type })),
|
|
12359
|
-
rows:
|
|
13231
|
+
rows: rel2.rows.map((r) => visible.map(({ i }) => r[i] ?? null)),
|
|
12360
13232
|
command,
|
|
12361
|
-
rowCount:
|
|
13233
|
+
rowCount: rel2.rows.length
|
|
12362
13234
|
};
|
|
12363
13235
|
}
|
|
12364
13236
|
function commandResult(command, rowCount) {
|
|
@@ -14617,31 +15489,31 @@ function makeEvalScope(env, scope, extras) {
|
|
|
14617
15489
|
return p;
|
|
14618
15490
|
},
|
|
14619
15491
|
execScalarSubquery(q) {
|
|
14620
|
-
const
|
|
14621
|
-
if (
|
|
15492
|
+
const rel2 = executeSelectStmt(childEnv(env, scope), q);
|
|
15493
|
+
if (rel2.columns.length !== 1) {
|
|
14622
15494
|
throw pgError("cardinality_violation", "subquery must return only one column", "42601");
|
|
14623
15495
|
}
|
|
14624
|
-
if (
|
|
15496
|
+
if (rel2.rows.length > 1) {
|
|
14625
15497
|
throw pgError(
|
|
14626
15498
|
"cardinality_violation",
|
|
14627
15499
|
"more than one row returned by a subquery used as an expression",
|
|
14628
15500
|
"21000"
|
|
14629
15501
|
);
|
|
14630
15502
|
}
|
|
14631
|
-
const t =
|
|
14632
|
-
return tv(t === UNKNOWN ? "text" : t,
|
|
15503
|
+
const t = rel2.columns[0].type;
|
|
15504
|
+
return tv(t === UNKNOWN ? "text" : t, rel2.rows[0]?.[0] ?? null);
|
|
14633
15505
|
},
|
|
14634
15506
|
execExistsSubquery(q) {
|
|
14635
|
-
const
|
|
14636
|
-
return
|
|
15507
|
+
const rel2 = executeSelectStmt(childEnv(env, scope), q);
|
|
15508
|
+
return rel2.rows.length > 0;
|
|
14637
15509
|
},
|
|
14638
15510
|
execColumnSubquery(q) {
|
|
14639
|
-
const
|
|
14640
|
-
if (
|
|
15511
|
+
const rel2 = executeSelectStmt(childEnv(env, scope), q);
|
|
15512
|
+
if (rel2.columns.length !== 1) {
|
|
14641
15513
|
throw pgError("cardinality_violation", "subquery has too many columns", "42601");
|
|
14642
15514
|
}
|
|
14643
|
-
const t =
|
|
14644
|
-
return { type: t === UNKNOWN ? "text" : t, values:
|
|
15515
|
+
const t = rel2.columns[0].type;
|
|
15516
|
+
return { type: t === UNKNOWN ? "text" : t, values: rel2.rows.map((r) => r[0] ?? null) };
|
|
14645
15517
|
},
|
|
14646
15518
|
aggValue(node) {
|
|
14647
15519
|
return extras?.aggMap?.get(node);
|
|
@@ -14757,39 +15629,39 @@ function referencesRelation(node, name) {
|
|
|
14757
15629
|
}
|
|
14758
15630
|
return false;
|
|
14759
15631
|
}
|
|
14760
|
-
function applyCteColumnNames(
|
|
14761
|
-
const columns =
|
|
15632
|
+
function applyCteColumnNames(rel2, cte) {
|
|
15633
|
+
const columns = rel2.columns.map((c, i) => ({
|
|
14762
15634
|
name: cte.columns?.[i] ?? c.name,
|
|
14763
15635
|
type: c.type,
|
|
14764
15636
|
table: null
|
|
14765
15637
|
}));
|
|
14766
|
-
if (cte.columns && cte.columns.length >
|
|
15638
|
+
if (cte.columns && cte.columns.length > rel2.columns.length) {
|
|
14767
15639
|
throw pgError(
|
|
14768
15640
|
"syntax",
|
|
14769
|
-
`WITH query "${cte.name}" has ${
|
|
15641
|
+
`WITH query "${cte.name}" has ${rel2.columns.length} columns available but ${cte.columns.length} columns specified`,
|
|
14770
15642
|
"42P10"
|
|
14771
15643
|
);
|
|
14772
15644
|
}
|
|
14773
|
-
return { columns, rows:
|
|
15645
|
+
return { columns, rows: rel2.rows };
|
|
14774
15646
|
}
|
|
14775
15647
|
function applyWith(env, w) {
|
|
14776
15648
|
if (!w) return env;
|
|
14777
15649
|
const ctes = new Map(env.ctes);
|
|
14778
15650
|
for (const cte of w.ctes) {
|
|
14779
15651
|
const scopedEnv = { ctx: env.ctx, params: env.params, ctes, outer: env.outer };
|
|
14780
|
-
let
|
|
15652
|
+
let rel2;
|
|
14781
15653
|
if (w.recursive && cte.query.type === "select" && cte.query.body.type === "setop" && cte.query.body.op === "union" && referencesRelation(cte.query.body.right, cte.name)) {
|
|
14782
|
-
|
|
15654
|
+
rel2 = executeRecursiveCte(scopedEnv, cte, cte.query);
|
|
14783
15655
|
} else if (cte.query.type === "select") {
|
|
14784
|
-
|
|
15656
|
+
rel2 = executeSelectStmt(scopedEnv, cte.query);
|
|
14785
15657
|
} else {
|
|
14786
15658
|
const res = runStatement(scopedEnv, cte.query);
|
|
14787
|
-
|
|
15659
|
+
rel2 = {
|
|
14788
15660
|
columns: res.columns.map((c) => ({ name: c.name, type: c.type, table: null })),
|
|
14789
15661
|
rows: res.rows
|
|
14790
15662
|
};
|
|
14791
15663
|
}
|
|
14792
|
-
ctes.set(cte.name, applyCteColumnNames(
|
|
15664
|
+
ctes.set(cte.name, applyCteColumnNames(rel2, cte));
|
|
14793
15665
|
}
|
|
14794
15666
|
return { ctx: env.ctx, params: env.params, ctes, outer: env.outer };
|
|
14795
15667
|
}
|
|
@@ -14848,28 +15720,28 @@ function executeRecursiveCte(env, cte, query) {
|
|
|
14848
15720
|
}
|
|
14849
15721
|
working = next;
|
|
14850
15722
|
}
|
|
14851
|
-
let
|
|
15723
|
+
let rel2 = { columns, rows: result };
|
|
14852
15724
|
if (query.orderBy.length > 0 || query.limit || query.offset) {
|
|
14853
|
-
const sortSpecs = outputOrderSpecs(env,
|
|
14854
|
-
if (sortSpecs.length > 0) sortRows(env,
|
|
14855
|
-
|
|
15725
|
+
const sortSpecs = outputOrderSpecs(env, rel2, query.orderBy);
|
|
15726
|
+
if (sortSpecs.length > 0) sortRows(env, rel2, sortSpecs);
|
|
15727
|
+
rel2 = applyLimitOffset(env, rel2, query.limit, query.offset);
|
|
14856
15728
|
}
|
|
14857
|
-
return
|
|
15729
|
+
return rel2;
|
|
14858
15730
|
}
|
|
14859
|
-
function renameWithAliases(
|
|
14860
|
-
if (colAliases && colAliases.length >
|
|
15731
|
+
function renameWithAliases(rel2, label, colAliases, what) {
|
|
15732
|
+
if (colAliases && colAliases.length > rel2.columns.length) {
|
|
14861
15733
|
throw pgError(
|
|
14862
15734
|
"invalid_column_reference",
|
|
14863
|
-
`table "${what}" has ${
|
|
15735
|
+
`table "${what}" has ${rel2.columns.length} columns available but ${colAliases.length} columns specified`,
|
|
14864
15736
|
"42P10"
|
|
14865
15737
|
);
|
|
14866
15738
|
}
|
|
14867
|
-
const columns =
|
|
15739
|
+
const columns = rel2.columns.map((c, i) => ({
|
|
14868
15740
|
name: colAliases?.[i] ?? c.name,
|
|
14869
15741
|
type: c.type === UNKNOWN ? "text" : c.type,
|
|
14870
15742
|
table: label
|
|
14871
15743
|
}));
|
|
14872
|
-
return { columns, rows:
|
|
15744
|
+
return { columns, rows: rel2.rows };
|
|
14873
15745
|
}
|
|
14874
15746
|
function materializeItem(env, item, scope) {
|
|
14875
15747
|
switch (item.type) {
|
|
@@ -14884,15 +15756,15 @@ function materializeItem(env, item, scope) {
|
|
|
14884
15756
|
const state = env.ctx.state;
|
|
14885
15757
|
const table = state.findTable(item.name);
|
|
14886
15758
|
if (table) {
|
|
14887
|
-
const
|
|
15759
|
+
const rel2 = {
|
|
14888
15760
|
columns: table.columns.map((c) => ({ name: c.name, type: c.type.id, table: label })),
|
|
14889
15761
|
rows: table.rows
|
|
14890
15762
|
};
|
|
14891
|
-
return { rel: renameWithAliases(
|
|
15763
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
14892
15764
|
}
|
|
14893
15765
|
const view = state.findView(item.name);
|
|
14894
15766
|
if (view) {
|
|
14895
|
-
let
|
|
15767
|
+
let rel2;
|
|
14896
15768
|
if (view.materialized) {
|
|
14897
15769
|
if (view.matRows === null || view.matColumns === null) {
|
|
14898
15770
|
throw pgError(
|
|
@@ -14901,23 +15773,23 @@ function materializeItem(env, item, scope) {
|
|
|
14901
15773
|
"55000"
|
|
14902
15774
|
);
|
|
14903
15775
|
}
|
|
14904
|
-
|
|
15776
|
+
rel2 = {
|
|
14905
15777
|
columns: view.matColumns.map((c) => ({ name: c.name, type: c.type, table: label })),
|
|
14906
15778
|
rows: view.matRows
|
|
14907
15779
|
};
|
|
14908
15780
|
} else {
|
|
14909
15781
|
const viewEnv = { ctx: env.ctx, params: null, ctes: /* @__PURE__ */ new Map(), outer: null };
|
|
14910
|
-
|
|
14911
|
-
|
|
14912
|
-
columns:
|
|
15782
|
+
rel2 = executeSelectStmt(viewEnv, view.query);
|
|
15783
|
+
rel2 = {
|
|
15784
|
+
columns: rel2.columns.map((c, i) => ({
|
|
14913
15785
|
name: view.columns?.[i] ?? c.name,
|
|
14914
15786
|
type: c.type,
|
|
14915
15787
|
table: label
|
|
14916
15788
|
})),
|
|
14917
|
-
rows:
|
|
15789
|
+
rows: rel2.rows
|
|
14918
15790
|
};
|
|
14919
15791
|
}
|
|
14920
|
-
return { rel: renameWithAliases(
|
|
15792
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
14921
15793
|
}
|
|
14922
15794
|
const resolved = state.resolveRelationSchema(item.name);
|
|
14923
15795
|
if (resolved) {
|
|
@@ -14930,9 +15802,9 @@ function materializeItem(env, item, scope) {
|
|
|
14930
15802
|
}
|
|
14931
15803
|
case "from_subquery": {
|
|
14932
15804
|
const subEnv = childEnv(env, item.lateral ? scope : env.outer);
|
|
14933
|
-
const
|
|
15805
|
+
const rel2 = executeSelectStmt(subEnv, item.query);
|
|
14934
15806
|
const label = item.alias ?? "unnamed_subquery";
|
|
14935
|
-
return { rel: renameWithAliases(
|
|
15807
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
14936
15808
|
}
|
|
14937
15809
|
case "from_func":
|
|
14938
15810
|
return materializeFunc(env, item, scope);
|
|
@@ -14969,7 +15841,7 @@ function srfCallRelation(env, call, scope, alias) {
|
|
|
14969
15841
|
}
|
|
14970
15842
|
function materializeFunc(env, item, scope) {
|
|
14971
15843
|
const effScope = scope ?? env.outer;
|
|
14972
|
-
let
|
|
15844
|
+
let rel2;
|
|
14973
15845
|
if (item.rowsFrom) {
|
|
14974
15846
|
const parts = item.rowsFrom.map((c) => srfCallRelation(env, c, effScope, null));
|
|
14975
15847
|
const maxLen = Math.max(0, ...parts.map((p) => p.rows.length));
|
|
@@ -14984,18 +15856,18 @@ function materializeFunc(env, item, scope) {
|
|
|
14984
15856
|
}
|
|
14985
15857
|
rows.push(row);
|
|
14986
15858
|
}
|
|
14987
|
-
|
|
15859
|
+
rel2 = { columns, rows };
|
|
14988
15860
|
} else {
|
|
14989
|
-
|
|
15861
|
+
rel2 = srfCallRelation(env, item.call, effScope, item.alias);
|
|
14990
15862
|
}
|
|
14991
15863
|
if (item.withOrdinality) {
|
|
14992
|
-
|
|
14993
|
-
columns: [...
|
|
14994
|
-
rows:
|
|
15864
|
+
rel2 = {
|
|
15865
|
+
columns: [...rel2.columns, { name: "ordinality", type: "int8", table: null }],
|
|
15866
|
+
rows: rel2.rows.map((r, i) => [...r, BigInt(i + 1)])
|
|
14995
15867
|
};
|
|
14996
15868
|
}
|
|
14997
15869
|
const label = item.alias ?? (item.call.type === "func" ? item.call.name[item.call.name.length - 1] : "unnamed_function");
|
|
14998
|
-
return { rel: renameWithAliases(
|
|
15870
|
+
return { rel: renameWithAliases(rel2, label, item.colAliases, label), rangeVars: /* @__PURE__ */ new Set([label]) };
|
|
14999
15871
|
}
|
|
15000
15872
|
function isLateralItem(item) {
|
|
15001
15873
|
switch (item.type) {
|
|
@@ -15524,9 +16396,9 @@ function computeAggregate(env, call, rows) {
|
|
|
15524
16396
|
for (const t of effective) acc.step(t.args);
|
|
15525
16397
|
return acc.result();
|
|
15526
16398
|
}
|
|
15527
|
-
function sortRows(env,
|
|
16399
|
+
function sortRows(env, rel2, specs) {
|
|
15528
16400
|
const ctx = env.ctx;
|
|
15529
|
-
const indexed =
|
|
16401
|
+
const indexed = rel2.rows.map((row, i) => ({ row, i }));
|
|
15530
16402
|
indexed.sort((a, b) => {
|
|
15531
16403
|
for (const s of specs) {
|
|
15532
16404
|
const av = a.row[s.colIdx] ?? null;
|
|
@@ -15538,14 +16410,14 @@ function sortRows(env, rel, specs) {
|
|
|
15538
16410
|
if (c2 !== 0) return c2;
|
|
15539
16411
|
continue;
|
|
15540
16412
|
}
|
|
15541
|
-
const t =
|
|
16413
|
+
const t = rel2.columns[s.colIdx].type;
|
|
15542
16414
|
let c = datumCompare(t === UNKNOWN ? "text" : t, av, bv, ctx);
|
|
15543
16415
|
if (s.dir === "desc") c = -c;
|
|
15544
16416
|
if (c !== 0) return c;
|
|
15545
16417
|
}
|
|
15546
16418
|
return a.i - b.i;
|
|
15547
16419
|
});
|
|
15548
|
-
|
|
16420
|
+
rel2.rows = indexed.map((x) => x.row);
|
|
15549
16421
|
}
|
|
15550
16422
|
function orderDirection(ob) {
|
|
15551
16423
|
let dir = ob.dir ?? "asc";
|
|
@@ -15554,30 +16426,30 @@ function orderDirection(ob) {
|
|
|
15554
16426
|
const nullsFirst = ob.nulls ? ob.nulls === "first" : dir === "desc";
|
|
15555
16427
|
return { dir, nullsFirst };
|
|
15556
16428
|
}
|
|
15557
|
-
function outputOrderSpecs(env,
|
|
16429
|
+
function outputOrderSpecs(env, rel2, orderBy) {
|
|
15558
16430
|
if (orderBy.length === 0) return [];
|
|
15559
16431
|
const specs = [];
|
|
15560
16432
|
const extraCols = [];
|
|
15561
16433
|
const extraExprs = [];
|
|
15562
16434
|
for (const ob of orderBy) {
|
|
15563
16435
|
const { dir, nullsFirst } = orderDirection(ob);
|
|
15564
|
-
const pos = orderPosition(ob.expr,
|
|
16436
|
+
const pos = orderPosition(ob.expr, rel2);
|
|
15565
16437
|
if (pos !== null) {
|
|
15566
16438
|
specs.push({ colIdx: pos, dir, nullsFirst });
|
|
15567
16439
|
continue;
|
|
15568
16440
|
}
|
|
15569
|
-
specs.push({ colIdx:
|
|
16441
|
+
specs.push({ colIdx: rel2.columns.length + extraCols.length, dir, nullsFirst });
|
|
15570
16442
|
extraCols.push({ name: `__ord${extraCols.length}`, type: UNKNOWN, table: null, hidden: true });
|
|
15571
16443
|
extraExprs.push(ob.expr);
|
|
15572
16444
|
}
|
|
15573
16445
|
if (extraExprs.length > 0) {
|
|
15574
|
-
const baseCols =
|
|
15575
|
-
|
|
15576
|
-
|
|
16446
|
+
const baseCols = rel2.columns.slice();
|
|
16447
|
+
rel2.columns = [...rel2.columns, ...extraCols];
|
|
16448
|
+
rel2.rows = rel2.rows.map((row) => {
|
|
15577
16449
|
const scope = new RowScope(baseCols, row, env.outer);
|
|
15578
16450
|
const extras = extraExprs.map((e) => evalScalar(env, scope, e));
|
|
15579
16451
|
for (let k = 0; k < extras.length; k++) {
|
|
15580
|
-
const col =
|
|
16452
|
+
const col = rel2.columns[baseCols.length + k];
|
|
15581
16453
|
col.type = unifyAggType(col.type, extras[k].t);
|
|
15582
16454
|
}
|
|
15583
16455
|
return [...row, ...extras.map((x) => x.v)];
|
|
@@ -15585,8 +16457,8 @@ function outputOrderSpecs(env, rel, orderBy) {
|
|
|
15585
16457
|
}
|
|
15586
16458
|
return specs;
|
|
15587
16459
|
}
|
|
15588
|
-
function orderPosition(e,
|
|
15589
|
-
const visible =
|
|
16460
|
+
function orderPosition(e, rel2) {
|
|
16461
|
+
const visible = rel2.columns.map((c, i) => ({ c, i })).filter(({ c }) => !c.hidden);
|
|
15590
16462
|
if (e.type === "number_lit" && /^\d+$/.test(e.raw)) {
|
|
15591
16463
|
const k = Number(e.raw);
|
|
15592
16464
|
const v = visible[k - 1];
|
|
@@ -15605,16 +16477,16 @@ function orderPosition(e, rel) {
|
|
|
15605
16477
|
}
|
|
15606
16478
|
return null;
|
|
15607
16479
|
}
|
|
15608
|
-
function stripHidden(
|
|
15609
|
-
if (!
|
|
15610
|
-
const keep =
|
|
16480
|
+
function stripHidden(rel2) {
|
|
16481
|
+
if (!rel2.columns.some((c) => c.hidden)) return rel2;
|
|
16482
|
+
const keep = rel2.columns.map((c, i) => ({ c, i })).filter(({ c }) => !c.hidden);
|
|
15611
16483
|
return {
|
|
15612
16484
|
columns: keep.map(({ c }) => c),
|
|
15613
|
-
rows:
|
|
16485
|
+
rows: rel2.rows.map((row) => keep.map(({ i }) => row[i] ?? null))
|
|
15614
16486
|
};
|
|
15615
16487
|
}
|
|
15616
|
-
function applyLimitOffset(env,
|
|
15617
|
-
let rows =
|
|
16488
|
+
function applyLimitOffset(env, rel2, limit, offset, tieSpecs) {
|
|
16489
|
+
let rows = rel2.rows;
|
|
15618
16490
|
if (offset) {
|
|
15619
16491
|
const v = evalScalar(env, env.outer, offset);
|
|
15620
16492
|
if (v.v !== null) {
|
|
@@ -15631,14 +16503,14 @@ function applyLimitOffset(env, rel, limit, offset, tieSpecs) {
|
|
|
15631
16503
|
let end = Math.min(n, rows.length);
|
|
15632
16504
|
if (tieSpecs && end > 0 && end < rows.length) {
|
|
15633
16505
|
const boundary = rows[end - 1];
|
|
15634
|
-
while (end < rows.length && sortKeysEqual(env,
|
|
16506
|
+
while (end < rows.length && sortKeysEqual(env, rel2, tieSpecs, boundary, rows[end])) end++;
|
|
15635
16507
|
}
|
|
15636
16508
|
rows = rows.slice(0, end);
|
|
15637
16509
|
}
|
|
15638
16510
|
}
|
|
15639
|
-
return { columns:
|
|
16511
|
+
return { columns: rel2.columns, rows };
|
|
15640
16512
|
}
|
|
15641
|
-
function sortKeysEqual(env,
|
|
16513
|
+
function sortKeysEqual(env, rel2, specs, a, b) {
|
|
15642
16514
|
for (const s of specs) {
|
|
15643
16515
|
const av = a[s.colIdx] ?? null;
|
|
15644
16516
|
const bv = b[s.colIdx] ?? null;
|
|
@@ -15646,7 +16518,7 @@ function sortKeysEqual(env, rel, specs, a, b) {
|
|
|
15646
16518
|
if (av !== bv) return false;
|
|
15647
16519
|
continue;
|
|
15648
16520
|
}
|
|
15649
|
-
const t =
|
|
16521
|
+
const t = rel2.columns[s.colIdx].type;
|
|
15650
16522
|
if (datumCompare(t === UNKNOWN ? "text" : t, av, bv, env.ctx) !== 0) return false;
|
|
15651
16523
|
}
|
|
15652
16524
|
return true;
|
|
@@ -15705,10 +16577,10 @@ function setOpRelation(env, op) {
|
|
|
15705
16577
|
return t === UNKNOWN ? "text" : t;
|
|
15706
16578
|
});
|
|
15707
16579
|
const columns = left.columns.map((c, i) => ({ name: c.name, type: types[i], table: null }));
|
|
15708
|
-
const normalize = (
|
|
16580
|
+
const normalize = (rel2) => rel2.rows.map(
|
|
15709
16581
|
(row) => row.map((v, i) => {
|
|
15710
16582
|
if (v === null) return null;
|
|
15711
|
-
const srcT =
|
|
16583
|
+
const srcT = rel2.columns[i].type;
|
|
15712
16584
|
if (srcT === types[i]) return v;
|
|
15713
16585
|
return castTo(ctx, tv(srcT === UNKNOWN ? "text" : srcT, v), types[i], {}).v;
|
|
15714
16586
|
})
|
|
@@ -16136,26 +17008,26 @@ function executeCore(env0, core, orderBy) {
|
|
|
16136
17008
|
outRows[r][k] = castTo(ctx, tv(cellT, v), finalT, { explicit: true }).v;
|
|
16137
17009
|
}
|
|
16138
17010
|
}
|
|
16139
|
-
let
|
|
17011
|
+
let rel2 = { columns: outColumns, rows: outRows };
|
|
16140
17012
|
if (sortSpecs.length > 0) {
|
|
16141
|
-
sortRows(env,
|
|
17013
|
+
sortRows(env, rel2, sortSpecs);
|
|
16142
17014
|
}
|
|
16143
17015
|
if (core.distinct) {
|
|
16144
17016
|
if (core.distinct.on) {
|
|
16145
17017
|
const seen = /* @__PURE__ */ new Set();
|
|
16146
|
-
|
|
17018
|
+
rel2.rows = rel2.rows.filter((row) => {
|
|
16147
17019
|
const k = distinctOnIdx.map((ci) => {
|
|
16148
17020
|
const v = row[ci] ?? null;
|
|
16149
|
-
return v === null ? "\0N" : datumKey(
|
|
17021
|
+
return v === null ? "\0N" : datumKey(rel2.columns[ci].type, v);
|
|
16150
17022
|
}).join("");
|
|
16151
17023
|
if (seen.has(k)) return false;
|
|
16152
17024
|
seen.add(k);
|
|
16153
17025
|
return true;
|
|
16154
17026
|
});
|
|
16155
17027
|
} else {
|
|
16156
|
-
const visible =
|
|
17028
|
+
const visible = rel2.columns.map((c, i) => ({ c, i })).filter(({ c }) => !c.hidden);
|
|
16157
17029
|
const seen = /* @__PURE__ */ new Set();
|
|
16158
|
-
|
|
17030
|
+
rel2.rows = rel2.rows.filter((row) => {
|
|
16159
17031
|
const k = visible.map(({ c, i }) => {
|
|
16160
17032
|
const v = row[i] ?? null;
|
|
16161
17033
|
return v === null ? "\0N" : datumKey(c.type, v);
|
|
@@ -16166,28 +17038,28 @@ function executeCore(env0, core, orderBy) {
|
|
|
16166
17038
|
});
|
|
16167
17039
|
}
|
|
16168
17040
|
}
|
|
16169
|
-
|
|
16170
|
-
return
|
|
17041
|
+
rel2 = stripHidden(rel2);
|
|
17042
|
+
return rel2;
|
|
16171
17043
|
}
|
|
16172
17044
|
function executeSelectStmt(env0, stmt) {
|
|
16173
17045
|
const env = applyWith(env0, stmt.with);
|
|
16174
|
-
let
|
|
17046
|
+
let rel2;
|
|
16175
17047
|
if (stmt.body.type === "select_core") {
|
|
16176
|
-
|
|
17048
|
+
rel2 = executeCore(env, stmt.body, stmt.orderBy);
|
|
16177
17049
|
} else {
|
|
16178
|
-
|
|
16179
|
-
const specs = outputOrderSpecs(env,
|
|
16180
|
-
if (specs.length > 0) sortRows(env,
|
|
16181
|
-
|
|
17050
|
+
rel2 = executeBody(env, stmt.body);
|
|
17051
|
+
const specs = outputOrderSpecs(env, rel2, stmt.orderBy);
|
|
17052
|
+
if (specs.length > 0) sortRows(env, rel2, specs);
|
|
17053
|
+
rel2 = stripHidden(rel2);
|
|
16182
17054
|
}
|
|
16183
17055
|
if (stmt.limitWithTies) {
|
|
16184
17056
|
if (stmt.orderBy.length === 0) {
|
|
16185
17057
|
throw pgError("syntax", "WITH TIES cannot be specified without ORDER BY clause", "42601");
|
|
16186
17058
|
}
|
|
16187
|
-
const tieSpecs = outputOrderSpecs(env,
|
|
16188
|
-
return stripHidden(applyLimitOffset(env,
|
|
17059
|
+
const tieSpecs = outputOrderSpecs(env, rel2, stmt.orderBy);
|
|
17060
|
+
return stripHidden(applyLimitOffset(env, rel2, stmt.limit, stmt.offset, tieSpecs));
|
|
16189
17061
|
}
|
|
16190
|
-
return applyLimitOffset(env,
|
|
17062
|
+
return applyLimitOffset(env, rel2, stmt.limit, stmt.offset);
|
|
16191
17063
|
}
|
|
16192
17064
|
|
|
16193
17065
|
// src/executor/triggers.ts
|
|
@@ -16195,6 +17067,9 @@ function matches(t, event) {
|
|
|
16195
17067
|
return t.events.some((e) => e.event === event);
|
|
16196
17068
|
}
|
|
16197
17069
|
var executor = null;
|
|
17070
|
+
function setTriggerExecutor(e) {
|
|
17071
|
+
executor = e;
|
|
17072
|
+
}
|
|
16198
17073
|
function fireRowTriggers(env, table, timing, event, oldRow, newRow) {
|
|
16199
17074
|
let row = newRow ?? oldRow;
|
|
16200
17075
|
for (const t of table.triggers) {
|
|
@@ -16209,6 +17084,261 @@ function fireRowTriggers(env, table, timing, event, oldRow, newRow) {
|
|
|
16209
17084
|
return { row };
|
|
16210
17085
|
}
|
|
16211
17086
|
|
|
17087
|
+
// src/executor/triggers-exec.ts
|
|
17088
|
+
var PlParser = class {
|
|
17089
|
+
constructor(src) {
|
|
17090
|
+
this.src = src;
|
|
17091
|
+
this.tokens = tokenize(src);
|
|
17092
|
+
}
|
|
17093
|
+
src;
|
|
17094
|
+
tokens;
|
|
17095
|
+
pos = 0;
|
|
17096
|
+
peek(offset = 0) {
|
|
17097
|
+
return this.tokens[Math.min(this.pos + offset, this.tokens.length - 1)];
|
|
17098
|
+
}
|
|
17099
|
+
next() {
|
|
17100
|
+
const t = this.peek();
|
|
17101
|
+
if (t.type !== "eof") this.pos++;
|
|
17102
|
+
return t;
|
|
17103
|
+
}
|
|
17104
|
+
atKw(kw) {
|
|
17105
|
+
const t = this.peek();
|
|
17106
|
+
return t.type === "ident" && t.value === kw;
|
|
17107
|
+
}
|
|
17108
|
+
expectKw(kw) {
|
|
17109
|
+
if (!this.atKw(kw)) throw unsupported(`trigger body: expected "${kw.toUpperCase()}" near "${this.peek().value}"`);
|
|
17110
|
+
this.pos++;
|
|
17111
|
+
}
|
|
17112
|
+
expectSemi() {
|
|
17113
|
+
const t = this.next();
|
|
17114
|
+
if (t.type !== "punct" || t.value !== ";") throw unsupported(`trigger body: expected ";" near "${t.value}"`);
|
|
17115
|
+
}
|
|
17116
|
+
parseBody() {
|
|
17117
|
+
if (this.atKw("declare")) throw unsupported("trigger body: DECLARE section");
|
|
17118
|
+
this.expectKw("begin");
|
|
17119
|
+
const stmts = this.parseStmts();
|
|
17120
|
+
this.expectKw("end");
|
|
17121
|
+
if (this.peek().type === "punct" && this.peek().value === ";") this.pos++;
|
|
17122
|
+
if (this.peek().type !== "eof") throw unsupported(`trigger body: trailing content near "${this.peek().value}"`);
|
|
17123
|
+
return stmts;
|
|
17124
|
+
}
|
|
17125
|
+
parseStmts() {
|
|
17126
|
+
const out = [];
|
|
17127
|
+
while (!this.atKw("end") && !this.atKw("elsif") && !this.atKw("else") && this.peek().type !== "eof") {
|
|
17128
|
+
out.push(this.parseStmt());
|
|
17129
|
+
}
|
|
17130
|
+
return out;
|
|
17131
|
+
}
|
|
17132
|
+
parseStmt() {
|
|
17133
|
+
if (this.atKw("return")) {
|
|
17134
|
+
this.pos++;
|
|
17135
|
+
const t = this.next();
|
|
17136
|
+
let what;
|
|
17137
|
+
if (t.type === "ident" && (t.value === "new" || t.value === "old" || t.value === "null")) {
|
|
17138
|
+
what = t.value;
|
|
17139
|
+
} else {
|
|
17140
|
+
throw unsupported(`trigger body: RETURN ${t.value}`);
|
|
17141
|
+
}
|
|
17142
|
+
this.expectSemi();
|
|
17143
|
+
return { kind: "return", what };
|
|
17144
|
+
}
|
|
17145
|
+
if (this.atKw("if")) {
|
|
17146
|
+
this.pos++;
|
|
17147
|
+
const branches = [];
|
|
17148
|
+
let elseBody = [];
|
|
17149
|
+
const cond = this.parseExprUntilKw("then");
|
|
17150
|
+
branches.push({ cond, body: this.parseStmts() });
|
|
17151
|
+
while (this.atKw("elsif")) {
|
|
17152
|
+
this.pos++;
|
|
17153
|
+
const c = this.parseExprUntilKw("then");
|
|
17154
|
+
branches.push({ cond: c, body: this.parseStmts() });
|
|
17155
|
+
}
|
|
17156
|
+
if (this.atKw("else")) {
|
|
17157
|
+
this.pos++;
|
|
17158
|
+
elseBody = this.parseStmts();
|
|
17159
|
+
}
|
|
17160
|
+
this.expectKw("end");
|
|
17161
|
+
this.expectKw("if");
|
|
17162
|
+
this.expectSemi();
|
|
17163
|
+
return { kind: "if", branches, elseBody };
|
|
17164
|
+
}
|
|
17165
|
+
if (this.atKw("null")) {
|
|
17166
|
+
this.pos++;
|
|
17167
|
+
this.expectSemi();
|
|
17168
|
+
return { kind: "null" };
|
|
17169
|
+
}
|
|
17170
|
+
if (this.atKw("raise")) {
|
|
17171
|
+
this.pos++;
|
|
17172
|
+
if (this.peek().type === "ident") this.pos++;
|
|
17173
|
+
let message = "";
|
|
17174
|
+
while (!(this.peek().type === "punct" && this.peek().value === ";") && this.peek().type !== "eof") {
|
|
17175
|
+
const t = this.next();
|
|
17176
|
+
if (t.type === "string" && message === "") message = t.value;
|
|
17177
|
+
}
|
|
17178
|
+
this.expectSemi();
|
|
17179
|
+
return { kind: "raise", message: message || "raised exception" };
|
|
17180
|
+
}
|
|
17181
|
+
const target = [];
|
|
17182
|
+
const first = this.next();
|
|
17183
|
+
if (first.type !== "ident" && first.type !== "quoted_ident") {
|
|
17184
|
+
throw unsupported(`trigger body statement near "${first.value}"`);
|
|
17185
|
+
}
|
|
17186
|
+
target.push(first.type === "ident" ? first.value : first.value);
|
|
17187
|
+
while (this.peek().type === "punct" && this.peek().value === ".") {
|
|
17188
|
+
this.pos++;
|
|
17189
|
+
const f = this.next();
|
|
17190
|
+
target.push(f.value);
|
|
17191
|
+
}
|
|
17192
|
+
const opTok = this.next();
|
|
17193
|
+
if (!(opTok.type === "op" && (opTok.value === ":=" || opTok.value === "="))) {
|
|
17194
|
+
throw unsupported(`trigger body: expected assignment near "${opTok.value}"`);
|
|
17195
|
+
}
|
|
17196
|
+
const expr = this.parseExprUntilSemi();
|
|
17197
|
+
return { kind: "assign", target, expr };
|
|
17198
|
+
}
|
|
17199
|
+
/** Slice raw source from the current token to the terminator and parse as a SQL expression. */
|
|
17200
|
+
parseExprUntilSemi() {
|
|
17201
|
+
const start = this.peek().pos;
|
|
17202
|
+
let depth = 0;
|
|
17203
|
+
for (; ; ) {
|
|
17204
|
+
const t = this.peek();
|
|
17205
|
+
if (t.type === "eof") throw unsupported("trigger body: unterminated statement");
|
|
17206
|
+
if (t.type === "punct" && t.value === "(") depth++;
|
|
17207
|
+
if (t.type === "punct" && t.value === ")") depth--;
|
|
17208
|
+
if (t.type === "punct" && t.value === ";" && depth === 0) {
|
|
17209
|
+
const text = this.src.slice(start, t.pos);
|
|
17210
|
+
this.pos++;
|
|
17211
|
+
return parseSqlExpr(text);
|
|
17212
|
+
}
|
|
17213
|
+
this.pos++;
|
|
17214
|
+
}
|
|
17215
|
+
}
|
|
17216
|
+
parseExprUntilKw(kw) {
|
|
17217
|
+
const start = this.peek().pos;
|
|
17218
|
+
let depth = 0;
|
|
17219
|
+
for (; ; ) {
|
|
17220
|
+
const t = this.peek();
|
|
17221
|
+
if (t.type === "eof") throw unsupported(`trigger body: expected "${kw.toUpperCase()}"`);
|
|
17222
|
+
if (t.type === "punct" && t.value === "(") depth++;
|
|
17223
|
+
if (t.type === "punct" && t.value === ")") depth--;
|
|
17224
|
+
if (t.type === "ident" && t.value === kw && depth === 0) {
|
|
17225
|
+
const text = this.src.slice(start, t.pos);
|
|
17226
|
+
this.pos++;
|
|
17227
|
+
return parseSqlExpr(text);
|
|
17228
|
+
}
|
|
17229
|
+
this.pos++;
|
|
17230
|
+
}
|
|
17231
|
+
}
|
|
17232
|
+
};
|
|
17233
|
+
function parseSqlExpr(text) {
|
|
17234
|
+
const stmts = parse(`SELECT ${text}`);
|
|
17235
|
+
const sel = stmts[0];
|
|
17236
|
+
const body = sel.body;
|
|
17237
|
+
const target = body.targets?.[0];
|
|
17238
|
+
if (!target) throw unsupported(`trigger body expression "${text}"`);
|
|
17239
|
+
return target.expr;
|
|
17240
|
+
}
|
|
17241
|
+
var bodyCache = /* @__PURE__ */ new Map();
|
|
17242
|
+
function compiledBody(fn) {
|
|
17243
|
+
const raw = fn.rawBody;
|
|
17244
|
+
if (raw === null) throw unsupported(`trigger function ${fn.name} has no body`);
|
|
17245
|
+
let cached = bodyCache.get(raw);
|
|
17246
|
+
if (cached === void 0) {
|
|
17247
|
+
cached = new PlParser(raw).parseBody();
|
|
17248
|
+
bodyCache.set(raw, cached);
|
|
17249
|
+
}
|
|
17250
|
+
return cached;
|
|
17251
|
+
}
|
|
17252
|
+
var ReturnSignal = class {
|
|
17253
|
+
constructor(row) {
|
|
17254
|
+
this.row = row;
|
|
17255
|
+
}
|
|
17256
|
+
row;
|
|
17257
|
+
};
|
|
17258
|
+
function runTriggerBody(env, table, stmts, vars) {
|
|
17259
|
+
const scope = () => triggerScope(table, vars.newRow, vars.oldRow);
|
|
17260
|
+
for (const stmt of stmts) {
|
|
17261
|
+
switch (stmt.kind) {
|
|
17262
|
+
case "assign": {
|
|
17263
|
+
if (stmt.target.length !== 2 || stmt.target[0] !== "new") {
|
|
17264
|
+
throw unsupported(`trigger body: assignment to "${stmt.target.join(".")}"`);
|
|
17265
|
+
}
|
|
17266
|
+
if (vars.newRow === null) {
|
|
17267
|
+
throw pgError("object_not_in_prerequisite_state", `record "new" is not assigned yet`, "55000");
|
|
17268
|
+
}
|
|
17269
|
+
const colName = stmt.target[1];
|
|
17270
|
+
const idx = table.columns.findIndex((c) => c.name === colName);
|
|
17271
|
+
if (idx === -1) {
|
|
17272
|
+
throw pgError("undefined_column", `record "new" has no field "${colName}"`, "42703");
|
|
17273
|
+
}
|
|
17274
|
+
const v = evalScalar(env, scope(), stmt.expr);
|
|
17275
|
+
vars.newRow = vars.newRow.slice();
|
|
17276
|
+
vars.newRow[idx] = v.v === null ? null : castTo(env.ctx, v, table.columns[idx].type.id, { assignment: true }).v;
|
|
17277
|
+
break;
|
|
17278
|
+
}
|
|
17279
|
+
case "return":
|
|
17280
|
+
throw new ReturnSignal(stmt.what === "new" ? vars.newRow : stmt.what === "old" ? vars.oldRow : null);
|
|
17281
|
+
case "if": {
|
|
17282
|
+
let taken = false;
|
|
17283
|
+
for (const b of stmt.branches) {
|
|
17284
|
+
if (evalPredicate(env, scope(), b.cond)) {
|
|
17285
|
+
runTriggerBody(env, table, b.body, vars);
|
|
17286
|
+
taken = true;
|
|
17287
|
+
break;
|
|
17288
|
+
}
|
|
17289
|
+
}
|
|
17290
|
+
if (!taken) runTriggerBody(env, table, stmt.elseBody, vars);
|
|
17291
|
+
break;
|
|
17292
|
+
}
|
|
17293
|
+
case "null":
|
|
17294
|
+
break;
|
|
17295
|
+
case "raise":
|
|
17296
|
+
throw pgError("raise_exception", stmt.message, "P0001");
|
|
17297
|
+
}
|
|
17298
|
+
}
|
|
17299
|
+
}
|
|
17300
|
+
function triggerScope(table, newRow, oldRow) {
|
|
17301
|
+
const cols = [];
|
|
17302
|
+
const row = [];
|
|
17303
|
+
const rangeVars = /* @__PURE__ */ new Set();
|
|
17304
|
+
if (newRow) {
|
|
17305
|
+
rangeVars.add("new");
|
|
17306
|
+
for (let i = 0; i < table.columns.length; i++) {
|
|
17307
|
+
cols.push({ name: table.columns[i].name, type: table.columns[i].type.id, table: "new" });
|
|
17308
|
+
row.push(newRow[i] ?? null);
|
|
17309
|
+
}
|
|
17310
|
+
}
|
|
17311
|
+
if (oldRow) {
|
|
17312
|
+
rangeVars.add("old");
|
|
17313
|
+
for (let i = 0; i < table.columns.length; i++) {
|
|
17314
|
+
cols.push({ name: table.columns[i].name, type: table.columns[i].type.id, table: "old" });
|
|
17315
|
+
row.push(oldRow[i] ?? null);
|
|
17316
|
+
}
|
|
17317
|
+
}
|
|
17318
|
+
return new RowScope(cols, row, null, rangeVars);
|
|
17319
|
+
}
|
|
17320
|
+
function executeTrigger(env, table, trigger, _event, oldRow, newRow) {
|
|
17321
|
+
const state = env.ctx.state;
|
|
17322
|
+
if (trigger.when !== null && !evalPredicate(env, triggerScope(table, newRow, oldRow), trigger.when)) {
|
|
17323
|
+
return newRow;
|
|
17324
|
+
}
|
|
17325
|
+
const fns = state.schemas.get(trigger.funcSchema)?.functions.get(trigger.funcName);
|
|
17326
|
+
const fn = fns?.[0];
|
|
17327
|
+
if (!fn) {
|
|
17328
|
+
throw pgError("undefined_function", `function ${trigger.funcSchema}.${trigger.funcName}() does not exist`, "42883");
|
|
17329
|
+
}
|
|
17330
|
+
const stmts = compiledBody(fn);
|
|
17331
|
+
const vars = { newRow: newRow ? newRow.slice() : null, oldRow };
|
|
17332
|
+
try {
|
|
17333
|
+
runTriggerBody(env, table, stmts, vars);
|
|
17334
|
+
} catch (e) {
|
|
17335
|
+
if (e instanceof ReturnSignal) return e.row;
|
|
17336
|
+
throw e;
|
|
17337
|
+
}
|
|
17338
|
+
throw pgError("invalid_function_definition", `control reached end of trigger procedure without RETURN`, "2F005");
|
|
17339
|
+
}
|
|
17340
|
+
setTriggerExecutor(executeTrigger);
|
|
17341
|
+
|
|
16212
17342
|
// src/expressions/context.ts
|
|
16213
17343
|
var EngineCtx = class {
|
|
16214
17344
|
state;
|
|
@@ -17093,8 +18223,8 @@ function executeCreateTableAs(env, stmt) {
|
|
|
17093
18223
|
if (stmt.ifNotExists) return commandResult("CREATE TABLE AS", 0);
|
|
17094
18224
|
throw pgError("duplicate_table", `relation "${name}" already exists`, "42P07");
|
|
17095
18225
|
}
|
|
17096
|
-
const
|
|
17097
|
-
const columns =
|
|
18226
|
+
const rel2 = executeSelectStmt(env, stmt.query);
|
|
18227
|
+
const columns = rel2.columns.map((c, i) => ({
|
|
17098
18228
|
name: stmt.columns?.[i] ?? c.name,
|
|
17099
18229
|
type: { id: c.type === UNKNOWN ? "text" : c.type, mod: null },
|
|
17100
18230
|
notNull: false,
|
|
@@ -17106,7 +18236,7 @@ function executeCreateTableAs(env, stmt) {
|
|
|
17106
18236
|
}));
|
|
17107
18237
|
const table = new TableData(schema.name, name, columns, state.nextOid(), stmt.temp);
|
|
17108
18238
|
if (stmt.withData) {
|
|
17109
|
-
table.rows =
|
|
18239
|
+
table.rows = rel2.rows.map((r) => r.slice());
|
|
17110
18240
|
}
|
|
17111
18241
|
schema.tables.set(name, table);
|
|
17112
18242
|
const count = stmt.withData ? table.rows.length : 0;
|
|
@@ -17177,12 +18307,12 @@ function executeCreateView(env, stmt) {
|
|
|
17177
18307
|
let matRows = null;
|
|
17178
18308
|
let matColumns = null;
|
|
17179
18309
|
if (stmt.materialized) {
|
|
17180
|
-
const
|
|
17181
|
-
matColumns =
|
|
18310
|
+
const rel2 = executeSelectStmt({ ctx: env.ctx, params: null, ctes: /* @__PURE__ */ new Map(), outer: null }, stmt.query);
|
|
18311
|
+
matColumns = rel2.columns.map((c, i) => ({
|
|
17182
18312
|
name: stmt.columns?.[i] ?? c.name,
|
|
17183
18313
|
type: c.type === UNKNOWN ? "text" : c.type
|
|
17184
18314
|
}));
|
|
17185
|
-
matRows = stmt.withData ?
|
|
18315
|
+
matRows = stmt.withData ? rel2.rows : null;
|
|
17186
18316
|
}
|
|
17187
18317
|
schema.views.set(name, {
|
|
17188
18318
|
name,
|
|
@@ -17202,12 +18332,12 @@ function executeRefreshMatView(env, stmt) {
|
|
|
17202
18332
|
if (!view?.materialized) {
|
|
17203
18333
|
throw pgError("undefined_table", `materialized view "${stmt.name.join(".")}" does not exist`, "42P01");
|
|
17204
18334
|
}
|
|
17205
|
-
const
|
|
17206
|
-
view.matColumns =
|
|
18335
|
+
const rel2 = executeSelectStmt({ ctx: env.ctx, params: null, ctes: /* @__PURE__ */ new Map(), outer: null }, view.query);
|
|
18336
|
+
view.matColumns = rel2.columns.map((c, i) => ({
|
|
17207
18337
|
name: view.columns?.[i] ?? c.name,
|
|
17208
18338
|
type: c.type === UNKNOWN ? "text" : c.type
|
|
17209
18339
|
}));
|
|
17210
|
-
view.matRows = stmt.withData ?
|
|
18340
|
+
view.matRows = stmt.withData ? rel2.rows : null;
|
|
17211
18341
|
return commandResult("REFRESH MATERIALIZED VIEW", 0);
|
|
17212
18342
|
}
|
|
17213
18343
|
function executeCreateSchema(env, stmt) {
|
|
@@ -18176,13 +19306,13 @@ function insertSourceRows(env, stmt, colIdxs) {
|
|
|
18176
19306
|
}
|
|
18177
19307
|
return rows;
|
|
18178
19308
|
}
|
|
18179
|
-
const
|
|
18180
|
-
if (
|
|
19309
|
+
const rel2 = executeSelectStmt(env, src);
|
|
19310
|
+
if (rel2.columns.length > colIdxs.length) {
|
|
18181
19311
|
throw pgError("syntax", "INSERT has more expressions than target columns", "42601");
|
|
18182
19312
|
}
|
|
18183
|
-
return
|
|
19313
|
+
return rel2.rows.map(
|
|
18184
19314
|
(r) => r.map((v, i) => {
|
|
18185
|
-
const t =
|
|
19315
|
+
const t = rel2.columns[i].type;
|
|
18186
19316
|
return tv(t === UNKNOWN ? "text" : t, v);
|
|
18187
19317
|
})
|
|
18188
19318
|
);
|
|
@@ -18345,21 +19475,21 @@ function applyUpdateSets(env, table, sets, scope, row) {
|
|
|
18345
19475
|
return i;
|
|
18346
19476
|
});
|
|
18347
19477
|
if (typeof set.value === "object" && "kind" in set.value && set.value.kind === "row_subquery") {
|
|
18348
|
-
const
|
|
19478
|
+
const rel2 = executeSelectStmt(
|
|
18349
19479
|
{ ctx: env.ctx, params: env.params, ctes: env.ctes, outer: scope },
|
|
18350
19480
|
set.value.query
|
|
18351
19481
|
);
|
|
18352
|
-
if (
|
|
19482
|
+
if (rel2.rows.length > 1) {
|
|
18353
19483
|
throw pgError(
|
|
18354
19484
|
"cardinality_violation",
|
|
18355
19485
|
"more than one row returned by a subquery used as an expression",
|
|
18356
19486
|
"21000"
|
|
18357
19487
|
);
|
|
18358
19488
|
}
|
|
18359
|
-
const srcRow =
|
|
19489
|
+
const srcRow = rel2.rows[0] ?? null;
|
|
18360
19490
|
for (let k = 0; k < colIdxs.length; k++) {
|
|
18361
19491
|
const col2 = table.columns[colIdxs[k]];
|
|
18362
|
-
const v = srcRow === null ? tv(col2.type.id, null) : tv(
|
|
19492
|
+
const v = srcRow === null ? tv(col2.type.id, null) : tv(rel2.columns[k]?.type ?? "text", srcRow[k] ?? null);
|
|
18363
19493
|
row[colIdxs[k]] = coerceToColumn(env, v.t === UNKNOWN ? tv("text", v.v) : v, col2);
|
|
18364
19494
|
}
|
|
18365
19495
|
continue;
|