qubu 0.6.1 → 0.6.2
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/{complete-DP7pliuY.mjs → canonical-B5_ouh-c.mjs} +466 -241
- package/dist/codegen.d.mts +2 -2
- package/dist/codegen.mjs +180 -90
- package/dist/column-Cyc2CMnG.mjs +116 -0
- package/dist/column-DDRvD7SF.mjs +721 -0
- package/dist/{constraints-DM_tarXc.mjs → constraints-CAmi18Uk.mjs} +8 -3
- package/dist/core.d.mts +3 -3
- package/dist/core.mjs +4 -4
- package/dist/diff.d.mts +9 -9
- package/dist/diff.mjs +152 -102
- package/dist/{explain-CkIK13L_.mjs → explain-BIqEmZha.mjs} +1 -1
- package/dist/{expressions-BCjc08zw.mjs → expressions-_6JF_J77.mjs} +2 -1
- package/dist/index-CaxrMD1A.d.mts +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +368 -74
- package/dist/introspection/mysql.d.mts +1 -1
- package/dist/introspection/mysql.mjs +156 -23
- package/dist/introspection/postgres.d.mts +6 -3
- package/dist/introspection/postgres.mjs +388 -53
- package/dist/introspection/sqlite.d.mts +1 -1
- package/dist/introspection/sqlite.mjs +198 -12
- package/dist/introspection.d.mts +26 -12
- package/dist/introspection.mjs +2 -672
- package/dist/mysql.d.mts +3 -3
- package/dist/mysql.mjs +6 -5
- package/dist/{errors-Dxv73YJu.mjs → omit-VEr9Ydux.mjs} +5 -1
- package/dist/{on-conflict-CnaY5qso.mjs → on-conflict-B2rFyHGF.mjs} +6 -8
- package/dist/on-duplicate-key-update-Czsw1Yq-.mjs +95 -0
- package/dist/{postgres-Dey7QXPL.mjs → postgres-hFhd0I9n.mjs} +4 -5
- package/dist/postgres.d.mts +2 -2
- package/dist/postgres.mjs +2 -2
- package/dist/{registry-oWDiqD7i.mjs → registry-BXE_4M9P.mjs} +1 -1
- package/dist/{relational-DSAJ-l58.mjs → relational-CoPBETjI.mjs} +3 -2
- package/dist/schema.d.mts +2 -2
- package/dist/schema.mjs +8 -8
- package/dist/{serialize-CE-gw5_s.mjs → serialize-CyobNEx-.mjs} +174 -30
- package/dist/serialize-Du2UPZMt.d.mts +92 -0
- package/dist/snapshot/mysql.d.mts +5 -5
- package/dist/snapshot/mysql.mjs +8 -8
- package/dist/snapshot/postgres.d.mts +3 -3
- package/dist/snapshot/postgres.mjs +9 -9
- package/dist/snapshot/sqlite.d.mts +3 -3
- package/dist/snapshot/sqlite.mjs +7 -7
- package/dist/snapshot-mIb-Zzb5.mjs +1489 -0
- package/dist/snapshot.d.mts +4 -5
- package/dist/snapshot.mjs +3 -4
- package/dist/{source-BDuUXmAk.mjs → source-DYSUqzvb.mjs} +2 -2
- package/dist/sqlite.d.mts +2 -2
- package/dist/sqlite.mjs +6 -6
- package/dist/{table-C1QGNe4P.mjs → table-B8zEq0az.mjs} +4 -4
- package/dist/{types-BLNRatG_.mjs → types-CYHpSPwj.mjs} +10 -5
- package/dist/{types-BEn0N_al.d.mts → types-CiMvKi5V.d.mts} +14 -4
- package/dist/{types-DUe6eeI0.d.mts → types-Dqr4o2I1.d.mts} +590 -168
- package/dist/value-CpaUFtjw.mjs +45 -0
- package/dist/vite/ambient.d.ts +2 -0
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +2 -0
- package/docs/dialects-and-execution.md +61 -11
- package/docs/getting-started.md +1 -1
- package/docs/guides/extensions/typed-expressions.md +5 -3
- package/docs/guides/json.md +95 -2
- package/docs/guides/mutations.md +36 -0
- package/docs/index.md +1 -1
- package/docs/migrations/adapters.md +58 -21
- package/docs/migrations/recovery.md +7 -1
- package/docs/query-model/fragments.md +21 -1
- package/docs/reference/introspection-support.md +16 -18
- package/docs/reference/supported-surface.md +8 -7
- package/docs/schema/catalog-model.md +20 -7
- package/docs/schema/code-generation.md +1 -1
- package/docs/schema/diff.md +2 -2
- package/docs/schema/introspection.md +21 -14
- package/docs/schema/snapshots.md +18 -8
- package/docs/schema/storage-and-schema-sql.md +7 -2
- package/package.json +2 -1
- package/dist/canonical-DMvR9yBe.mjs +0 -972
- package/dist/column-BzN8KFJa.mjs +0 -364
- package/dist/column-CFvSbil0.mjs +0 -309
- package/dist/complete-types-CNMWBWap.d.mts +0 -371
- package/dist/index-CGui70hi.d.mts +0 -32
- package/dist/json-Db7XRD91.mjs +0 -169
- package/dist/omit-OxV58AwX.mjs +0 -5
- package/dist/serialize-OvXCLzjm.d.mts +0 -66
- package/dist/snapshot-DgsOhf_8.mjs +0 -354
|
@@ -9,6 +9,8 @@ const postgresServerQuery = `
|
|
|
9
9
|
/** Read one PostgreSQL schema into the normalized catalog contract. */
|
|
10
10
|
async function readCatalog(connection, options) {
|
|
11
11
|
const diagnostics = [];
|
|
12
|
+
const deferredObjects = [];
|
|
13
|
+
const opaqueObjects = [];
|
|
12
14
|
if (connection.dialect !== "postgresql") {
|
|
13
15
|
diagnostics.push(createIntrospectionDiagnostic({
|
|
14
16
|
severity: "error",
|
|
@@ -54,24 +56,35 @@ async function readCatalog(connection, options) {
|
|
|
54
56
|
for (const row of indexRows) {
|
|
55
57
|
const indexOid = text(row.index_oid);
|
|
56
58
|
const physicalName = text(row.physical_name);
|
|
59
|
+
const ownerTable = tableByOid.get(text(row.table_oid));
|
|
57
60
|
if (indexOid && physicalName) indexReferences.set(`pg_class:${indexOid}`, {
|
|
58
61
|
kind: "index",
|
|
59
62
|
id: stableId(physicalName),
|
|
60
63
|
physicalName,
|
|
64
|
+
...ownerTable === void 0 ? {} : { owner: {
|
|
65
|
+
kind: "table",
|
|
66
|
+
id: ownerTable.id
|
|
67
|
+
} },
|
|
61
68
|
reference: reference("index", physicalName, options.namespace, "pg_class", "oid", row.index_oid)
|
|
62
69
|
});
|
|
63
70
|
}
|
|
64
|
-
const constraintsByTable = groupBy(await query(connection, postgresConstraintsQuery, [options.namespace], options, diagnostics, "constraints"), (row) => row.table_oid);
|
|
71
|
+
const constraintsByTable = groupBy(await query(connection, (server.parsedVersion?.major ?? 0) >= 15 ? postgresConstraintsQuery : postgresConstraintsQueryWithoutNullsNotDistinct, [options.namespace], options, diagnostics, "constraints"), (row) => row.table_oid);
|
|
65
72
|
for (const table of tables) {
|
|
66
73
|
const rows = constraintsByTable.get(table.reference?.catalog?.value) ?? [];
|
|
67
74
|
const columnsByNumber = new Map(table.columns.map((column) => [column.ordinalPosition, column.physicalName]));
|
|
68
|
-
|
|
75
|
+
const constraints = [];
|
|
76
|
+
for (const value of rows.map((row) => constraint(row, table, columnsByNumber, tableByOid, options.namespace, diagnostics, indexReferences))) {
|
|
77
|
+
if (value === void 0) continue;
|
|
78
|
+
if (value.kind === "opaque-object") opaqueObjects.push(value);
|
|
79
|
+
else constraints.push(value);
|
|
80
|
+
}
|
|
81
|
+
table.constraints = constraints;
|
|
69
82
|
}
|
|
70
83
|
const indexesByTable = groupBy(indexRows, (row) => row.table_oid);
|
|
71
|
-
for (const table of tables) table.indexes = mapIndexes(indexesByTable.get(table.reference?.catalog?.value) ?? [], table, new Map(table.columns.map((column) => [column.ordinalPosition, column.physicalName])), options.namespace);
|
|
84
|
+
for (const table of tables) table.indexes = mapIndexes(indexesByTable.get(table.reference?.catalog?.value) ?? [], table, new Map(table.columns.map((column) => [column.ordinalPosition, column.physicalName])), options.namespace, diagnostics, opaqueObjects);
|
|
72
85
|
const sequences = (await query(connection, postgresSequencesQuery, [options.namespace], options, diagnostics, "sequences")).map((row) => sequenceObject(row, options.namespace, tableByOid, diagnostics));
|
|
73
86
|
const enums = mapEnums(await query(connection, postgresEnumsQuery, [options.namespace], options, diagnostics, "enums"), options.namespace);
|
|
74
|
-
const domains = mapDomains(await query(connection, postgresDomainsQuery, [options.namespace], options, diagnostics, "domains"), await query(connection, postgresDomainConstraintsQuery, [options.namespace], options, diagnostics, "domain-constraints"), options.namespace);
|
|
87
|
+
const domains = mapDomains(await query(connection, postgresDomainsQuery, [options.namespace], options, diagnostics, "domains"), await query(connection, postgresDomainConstraintsQuery, [options.namespace], options, diagnostics, "domain-constraints"), options.namespace, opaqueObjects, diagnostics);
|
|
75
88
|
const collations = (await query(connection, postgresCollationsQuery, [options.namespace], options, diagnostics, "collations")).map((row) => collationObject(row, options.namespace));
|
|
76
89
|
const triggerRows = await query(connection, postgresTriggersQuery, [options.namespace], options, diagnostics, "triggers");
|
|
77
90
|
const triggers = [];
|
|
@@ -82,19 +95,27 @@ async function readCatalog(connection, options) {
|
|
|
82
95
|
else triggers.push(value);
|
|
83
96
|
}
|
|
84
97
|
const routines = mapRoutines(await query(connection, postgresRoutinesQuery, [options.namespace], options, diagnostics, "routines"), await query(connection, postgresRoutineParametersQuery, [options.namespace], options, diagnostics, "routine-parameters"), options.namespace, diagnostics);
|
|
85
|
-
const
|
|
98
|
+
const partitionRows = await query(connection, postgresPartitionsQuery, [options.namespace], options, diagnostics, "partitions");
|
|
99
|
+
const partitions = [];
|
|
100
|
+
for (const row of partitionRows) {
|
|
101
|
+
const value = partitionObject(row, options.namespace, tableByOid, diagnostics);
|
|
102
|
+
if (value === void 0) continue;
|
|
103
|
+
if (value.kind === "partition") partitions.push(value);
|
|
104
|
+
else if (value.kind === "deferred-object") deferredObjects.push(value);
|
|
105
|
+
else opaqueObjects.push(value);
|
|
106
|
+
}
|
|
86
107
|
const policies = (await query(connection, postgresPoliciesQuery, [options.namespace], options, diagnostics, "policies")).map((row) => policyObject(row, options.namespace, tableByOid, diagnostics)).filter((value) => value !== void 0);
|
|
87
108
|
const extensionObjects = (await query(connection, postgresExtensionsQuery, [options.namespace], options, diagnostics, "extensions")).map((row) => extensionObject(row, options.namespace));
|
|
88
109
|
const typedRelationOids = new Set([...views, ...sequences].map((object) => object.reference?.catalog?.value));
|
|
89
|
-
|
|
110
|
+
deferredObjects.push(...relationObjects.filter((row) => {
|
|
90
111
|
const relkind = text(row.relkind);
|
|
91
112
|
return relkind === "f" || (relkind === "v" || relkind === "m" || relkind === "S") && !typedRelationOids.has(row.oid === void 0 ? void 0 : text(row.oid));
|
|
92
|
-
}).map((row) => deferredObject(row, text(row.relkind) === "f" ? "foreign-table" : text(row.relkind) === "v" ? "view" : text(row.relkind) === "m" ? "materialized-view" : "sequence"));
|
|
113
|
+
}).map((row) => deferredObject(row, text(row.relkind) === "f" ? "foreign-table" : text(row.relkind) === "v" ? "view" : text(row.relkind) === "m" ? "materialized-view" : "sequence")));
|
|
93
114
|
deferredObjects.push(...triggerDeferredObjects);
|
|
94
|
-
|
|
115
|
+
opaqueObjects.push(...relationObjects.filter((row) => {
|
|
95
116
|
const kind = text(row.relkind);
|
|
96
117
|
return kind !== "r" && kind !== "p" && kind !== "v" && kind !== "m" && kind !== "S" && kind !== "f";
|
|
97
|
-
}).map((row) => opaqueRelationObject(row, options.namespace, diagnostics));
|
|
118
|
+
}).map((row) => opaqueRelationObject(row, options.namespace, diagnostics)));
|
|
98
119
|
const metadata = mapMetadataRows(await query(connection, postgresMetadataQuery, [options.namespace], options, diagnostics, "comments-and-ownership"), options.namespace, tables, views, sequences, enums, domains, collations, routines, triggers, policies, extensionObjects, deferredObjects, opaqueObjects, indexReferences, relationReferences, diagnostics);
|
|
99
120
|
opaqueObjects.push(...metadata.opaqueObjects);
|
|
100
121
|
return Object.freeze({
|
|
@@ -161,6 +182,24 @@ const postgresColumnsQuery = `
|
|
|
161
182
|
AND NOT a.attisdropped
|
|
162
183
|
ORDER BY a.attrelid, a.attnum
|
|
163
184
|
`;
|
|
185
|
+
/** Constraint metadata for PostgreSQL versions before pg_index.indnullsnotdistinct. */
|
|
186
|
+
const postgresConstraintsQueryWithoutNullsNotDistinct = `
|
|
187
|
+
SELECT con.oid::text AS oid, con.conrelid::text AS table_oid,
|
|
188
|
+
con.conname AS physical_name, con.contype,
|
|
189
|
+
con.conkey, con.confrelid::text AS target_table_oid, con.confkey,
|
|
190
|
+
con.confupdtype, con.confdeltype, con.confmatchtype,
|
|
191
|
+
con.condeferrable, con.condeferred, con.convalidated,
|
|
192
|
+
con.conindid::text AS backing_index_oid,
|
|
193
|
+
pg_get_constraintdef(con.oid, true) AS definition
|
|
194
|
+
FROM pg_constraint con
|
|
195
|
+
JOIN pg_class c ON c.oid = con.conrelid
|
|
196
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
197
|
+
LEFT JOIN pg_index i ON i.indexrelid = con.conindid
|
|
198
|
+
WHERE n.nspname = $1
|
|
199
|
+
AND con.contype IN ('p', 'u', 'f', 'c', 'x')
|
|
200
|
+
ORDER BY con.conrelid, con.oid
|
|
201
|
+
`;
|
|
202
|
+
/** Constraint metadata for PostgreSQL versions that expose nulls-not-distinct indexes. */
|
|
164
203
|
const postgresConstraintsQuery = `
|
|
165
204
|
SELECT con.oid::text AS oid, con.conrelid::text AS table_oid,
|
|
166
205
|
con.conname AS physical_name, con.contype,
|
|
@@ -326,6 +365,7 @@ const postgresPartitionsQuery = `
|
|
|
326
365
|
SELECT child.oid::text AS partition_oid, parent.oid::text AS parent_oid,
|
|
327
366
|
n.nspname AS namespace, child.relname AS physical_name,
|
|
328
367
|
part.partstrat, part.partattrs::text AS key_attributes,
|
|
368
|
+
pg_get_partkeydef(parent.oid) AS key_definition,
|
|
329
369
|
pg_get_expr(child.relpartbound, child.oid, true) AS bound,
|
|
330
370
|
child.relispartition, child.relkind
|
|
331
371
|
FROM pg_catalog.pg_inherits inh
|
|
@@ -544,10 +584,7 @@ function viewObject(row, namespace, diagnostics) {
|
|
|
544
584
|
physicalReference,
|
|
545
585
|
remediation: "Grant access to pg_get_viewdef before treating this object as migration input."
|
|
546
586
|
}));
|
|
547
|
-
return deferredCatalogObject(kind === "view" ? "view" : "materialized-view", physicalName, physicalReference
|
|
548
|
-
name: "definition",
|
|
549
|
-
value: expression("/* view definition unavailable */", "decompiler", physicalReference)
|
|
550
|
-
}]);
|
|
587
|
+
return deferredCatalogObject(kind === "view" ? "view" : "materialized-view", physicalName, physicalReference);
|
|
551
588
|
}
|
|
552
589
|
const options = stringArray(row.reloptions);
|
|
553
590
|
const checkOption = (() => {
|
|
@@ -672,7 +709,7 @@ function mapEnums(rows, namespace) {
|
|
|
672
709
|
};
|
|
673
710
|
});
|
|
674
711
|
}
|
|
675
|
-
function mapDomains(rows, constraintRows, namespace) {
|
|
712
|
+
function mapDomains(rows, constraintRows, namespace, opaqueObjects, diagnostics) {
|
|
676
713
|
const constraintsByDomain = groupBy(constraintRows, (row) => text(row.domain_oid) ?? "unknown");
|
|
677
714
|
return rows.map((row) => {
|
|
678
715
|
const physicalName = text(row.physical_name) ?? `domain_${text(row.oid) ?? "unknown"}`;
|
|
@@ -680,18 +717,37 @@ function mapDomains(rows, constraintRows, namespace) {
|
|
|
680
717
|
const domainConstraints = (constraintsByDomain.get(text(row.oid)) ?? []).map((constraintRow) => {
|
|
681
718
|
const constraintName = text(constraintRow.physical_name) ?? `domain_constraint_${text(constraintRow.oid) ?? "unknown"}`;
|
|
682
719
|
const constraintReference = reference("constraint", constraintName, text(row.namespace) ?? namespace, "pg_constraint", "oid", constraintRow.oid);
|
|
720
|
+
const definition = text(constraintRow.definition);
|
|
721
|
+
if (definition === void 0 || definition.trim() === "") {
|
|
722
|
+
diagnostics.push(createIntrospectionDiagnostic({
|
|
723
|
+
severity: "warning",
|
|
724
|
+
code: "unmodeled-object",
|
|
725
|
+
message: `PostgreSQL domain constraint ${constraintName} has no recoverable definition`,
|
|
726
|
+
path: [
|
|
727
|
+
"domains",
|
|
728
|
+
physicalName,
|
|
729
|
+
"constraints",
|
|
730
|
+
constraintName
|
|
731
|
+
],
|
|
732
|
+
physicalReference: constraintReference,
|
|
733
|
+
remediation: "Inspect the opaque domain constraint before using it as migration input."
|
|
734
|
+
}));
|
|
735
|
+
opaqueObjects.push(opaqueDomainConstraint(physicalName, constraintName, constraintReference, void 0));
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
683
738
|
return {
|
|
684
739
|
kind: "check",
|
|
685
740
|
id: stableId(constraintName),
|
|
686
741
|
identitySource: "physical-name",
|
|
687
742
|
physicalName: constraintName,
|
|
688
|
-
expression: expression(
|
|
743
|
+
expression: expression(definition, "decompiler", constraintReference),
|
|
689
744
|
deferrable: constraintRow.condeferrable === void 0 ? void 0 : boolean(constraintRow.condeferrable),
|
|
690
745
|
initially: constraintRow.condeferred === void 0 ? void 0 : boolean(constraintRow.condeferred) ? "deferred" : "immediate",
|
|
691
746
|
validated: constraintRow.convalidated === void 0 ? void 0 : boolean(constraintRow.convalidated),
|
|
692
747
|
reference: constraintReference
|
|
693
748
|
};
|
|
694
|
-
});
|
|
749
|
+
}).filter((value) => value !== void 0);
|
|
750
|
+
const defaultValue = domainDefault(row.default_expression, physicalReference);
|
|
695
751
|
return {
|
|
696
752
|
kind: "domain",
|
|
697
753
|
id: stableId(physicalName),
|
|
@@ -699,12 +755,73 @@ function mapDomains(rows, constraintRows, namespace) {
|
|
|
699
755
|
physicalName,
|
|
700
756
|
storage: storage(row.native_type),
|
|
701
757
|
...row.nullable === void 0 || row.nullable === null ? {} : { nullable: boolean(row.nullable) },
|
|
702
|
-
...
|
|
758
|
+
...defaultValue === void 0 ? {} : { default: defaultValue },
|
|
703
759
|
...domainConstraints.length === 0 ? {} : { constraints: domainConstraints },
|
|
704
760
|
reference: physicalReference
|
|
705
761
|
};
|
|
706
762
|
});
|
|
707
763
|
}
|
|
764
|
+
function opaqueDomainConstraint(domainName, constraintName, physicalReference, definition) {
|
|
765
|
+
return {
|
|
766
|
+
kind: "opaque-object",
|
|
767
|
+
id: stableId(`domain-constraint:${domainName}:${constraintName}`),
|
|
768
|
+
identitySource: "physical-name",
|
|
769
|
+
objectKind: "domain-constraint",
|
|
770
|
+
physicalName: constraintName,
|
|
771
|
+
data: {
|
|
772
|
+
domain: domainName,
|
|
773
|
+
definitionAvailable: definition !== void 0
|
|
774
|
+
},
|
|
775
|
+
...definition === void 0 ? {} : { sql: expression(definition, "decompiler", physicalReference) },
|
|
776
|
+
reference: physicalReference,
|
|
777
|
+
provenance: {
|
|
778
|
+
kind: "catalog",
|
|
779
|
+
dialect: "postgresql",
|
|
780
|
+
reference: physicalReference
|
|
781
|
+
}
|
|
782
|
+
};
|
|
783
|
+
}
|
|
784
|
+
function domainDefault(value, physicalReference) {
|
|
785
|
+
const textValue = text(value);
|
|
786
|
+
if (textValue === void 0 || textValue.trim() === "") return;
|
|
787
|
+
const trimmed = textValue.trim();
|
|
788
|
+
if (/^NULL$/i.test(trimmed)) return {
|
|
789
|
+
kind: "literal",
|
|
790
|
+
value: null
|
|
791
|
+
};
|
|
792
|
+
if (/^TRUE$/i.test(trimmed)) return {
|
|
793
|
+
kind: "literal",
|
|
794
|
+
value: true
|
|
795
|
+
};
|
|
796
|
+
if (/^FALSE$/i.test(trimmed)) return {
|
|
797
|
+
kind: "literal",
|
|
798
|
+
value: false
|
|
799
|
+
};
|
|
800
|
+
if (/^[+-]?\d+$/.test(trimmed)) {
|
|
801
|
+
const fact = literalFact(trimmed);
|
|
802
|
+
if (fact !== void 0) return fact;
|
|
803
|
+
}
|
|
804
|
+
if (/^[+-]?\d+\.\d+$/.test(trimmed)) {
|
|
805
|
+
const fact = literalFact(trimmed);
|
|
806
|
+
if (fact?.value !== void 0 && typeof fact.value === "number" && canonicalDecimal(trimmed) === canonicalDecimal(String(fact.value))) return fact;
|
|
807
|
+
}
|
|
808
|
+
if (trimmed.match(/^'(?:''|[^'])*'$/)) return {
|
|
809
|
+
kind: "literal",
|
|
810
|
+
value: trimmed.slice(1, -1).replace(/''/g, "'")
|
|
811
|
+
};
|
|
812
|
+
return {
|
|
813
|
+
kind: "expression",
|
|
814
|
+
expression: expression(textValue, "catalog", physicalReference)
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
function canonicalDecimal(value) {
|
|
818
|
+
const match = value.match(/^([+-]?)(\d+)(?:\.(\d+))?$/);
|
|
819
|
+
if (!match) return;
|
|
820
|
+
const sign = match[1] === "-" ? "-" : "";
|
|
821
|
+
const integer = match[2].replace(/^0+(?=\d)/, "");
|
|
822
|
+
const fraction = (match[3] ?? "").replace(/0+$/, "");
|
|
823
|
+
return `${sign}${integer}${fraction === "" ? "" : `.${fraction}`}`;
|
|
824
|
+
}
|
|
708
825
|
function collationObject(row, namespace) {
|
|
709
826
|
const physicalName = text(row.physical_name) ?? `collation_${text(row.oid) ?? "unknown"}`;
|
|
710
827
|
return {
|
|
@@ -836,41 +953,139 @@ function mapRoutines(rows, parameterRows, namespace, diagnostics) {
|
|
|
836
953
|
function partitionObject(row, namespace, tableByOid, diagnostics) {
|
|
837
954
|
const physicalName = text(row.physical_name) ?? `partition_${text(row.partition_oid) ?? "unknown"}`;
|
|
838
955
|
const physicalReference = reference("partition", physicalName, text(row.namespace) ?? namespace, "pg_class", "oid", row.partition_oid);
|
|
956
|
+
if (!boolean(row.relispartition)) return inheritanceObject(row, namespace, diagnostics);
|
|
839
957
|
const parent = tableByOid.get(text(row.parent_oid));
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
958
|
+
const keyDefinition = text(row.key_definition);
|
|
959
|
+
const bound = text(row.bound);
|
|
960
|
+
if (parent === void 0) {
|
|
961
|
+
diagnostics.push(createIntrospectionDiagnostic({
|
|
962
|
+
severity: "error",
|
|
963
|
+
code: "unresolved-reference",
|
|
964
|
+
message: `PostgreSQL partition ${physicalName} has no parent table in the selected schema`,
|
|
965
|
+
path: [
|
|
966
|
+
"partitions",
|
|
967
|
+
physicalName,
|
|
968
|
+
"parent"
|
|
969
|
+
],
|
|
970
|
+
physicalReference,
|
|
971
|
+
remediation: "Select the parent table schema before mapping partitions."
|
|
972
|
+
}));
|
|
973
|
+
return deferredCatalogObject("partition", physicalName, physicalReference, [
|
|
974
|
+
...text(row.parent_oid) === void 0 ? [] : [{
|
|
975
|
+
name: "parentOid",
|
|
976
|
+
value: text(row.parent_oid)
|
|
977
|
+
}],
|
|
978
|
+
...text(row.key_attributes) === void 0 ? [] : [{
|
|
979
|
+
name: "keyAttributes",
|
|
980
|
+
value: text(row.key_attributes)
|
|
981
|
+
}],
|
|
982
|
+
...keyDefinition === void 0 ? [] : [{
|
|
983
|
+
name: "keyDefinition",
|
|
984
|
+
value: expression(keyDefinition, "decompiler", physicalReference)
|
|
985
|
+
}],
|
|
986
|
+
...bound === void 0 ? [] : [{
|
|
987
|
+
name: "bound",
|
|
988
|
+
value: expression(bound, "decompiler", physicalReference)
|
|
989
|
+
}]
|
|
990
|
+
]);
|
|
991
|
+
}
|
|
992
|
+
const keyInfo = partitionKeyInfo(row.key_attributes, parent.columns);
|
|
993
|
+
const unknownFields = [];
|
|
994
|
+
if (keyDefinition !== void 0 && (keyInfo.hasExpression || keyInfo.missingPositions.length > 0 || keyInfo.columns.length === 0)) unknownFields.push({
|
|
995
|
+
name: "keyDefinition",
|
|
996
|
+
value: expression(keyDefinition, "decompiler", physicalReference)
|
|
997
|
+
});
|
|
998
|
+
if (keyInfo.missingPositions.length > 0 || keyInfo.hasExpression && keyDefinition === void 0) {
|
|
999
|
+
const keyAttributes = text(row.key_attributes);
|
|
1000
|
+
if (keyAttributes !== void 0) unknownFields.push({
|
|
1001
|
+
name: "keyAttributes",
|
|
1002
|
+
value: keyAttributes
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
if (keyInfo.hasExpression) diagnostics.push(createIntrospectionDiagnostic({
|
|
1006
|
+
severity: "warning",
|
|
1007
|
+
code: "unsupported-feature",
|
|
1008
|
+
message: `PostgreSQL partition ${physicalName} has an expression key retained as dialect evidence`,
|
|
844
1009
|
path: [
|
|
845
1010
|
"partitions",
|
|
846
1011
|
physicalName,
|
|
847
|
-
"
|
|
1012
|
+
"keyDefinition"
|
|
848
1013
|
],
|
|
849
1014
|
physicalReference,
|
|
850
|
-
remediation: "
|
|
1015
|
+
remediation: "Inspect the retained partition key definition before using it as migration input."
|
|
1016
|
+
}));
|
|
1017
|
+
if (keyInfo.missingPositions.length > 0) diagnostics.push(createIntrospectionDiagnostic({
|
|
1018
|
+
severity: "warning",
|
|
1019
|
+
code: "unresolved-reference",
|
|
1020
|
+
message: `PostgreSQL partition ${physicalName} has unknown key attributes`,
|
|
1021
|
+
path: [
|
|
1022
|
+
"partitions",
|
|
1023
|
+
physicalName,
|
|
1024
|
+
"keyAttributes"
|
|
1025
|
+
],
|
|
1026
|
+
physicalReference
|
|
851
1027
|
}));
|
|
852
|
-
const parentReference = parent ? {
|
|
853
|
-
kind: "table",
|
|
854
|
-
id: parent.id
|
|
855
|
-
} : {
|
|
856
|
-
kind: "table",
|
|
857
|
-
id: stableId(`missing_parent_${text(row.parent_oid) ?? "unknown"}`)
|
|
858
|
-
};
|
|
859
|
-
const keyColumns = partitionKeyColumns(row.key_attributes, parent?.columns ?? []);
|
|
860
|
-
const bound = text(row.bound);
|
|
861
1028
|
return {
|
|
862
1029
|
kind: "partition",
|
|
863
1030
|
id: stableId(physicalName),
|
|
864
1031
|
identitySource: "physical-name",
|
|
865
1032
|
physicalName,
|
|
866
|
-
parent:
|
|
1033
|
+
parent: {
|
|
1034
|
+
kind: "table",
|
|
1035
|
+
id: parent.id
|
|
1036
|
+
},
|
|
867
1037
|
strategy: partitionStrategy(row.partstrat),
|
|
868
|
-
...
|
|
1038
|
+
...keyInfo.hasExpression || keyInfo.missingPositions.length > 0 || keyInfo.columns.length === 0 ? {} : { keyColumns: keyInfo.columns },
|
|
869
1039
|
...bound === void 0 ? {} : { bound: expression(bound, "decompiler", physicalReference) },
|
|
870
1040
|
...bound !== void 0 && /^default$/i.test(bound.trim()) ? { default: true } : {},
|
|
1041
|
+
...unknownFields.length === 0 ? {} : { unknownFields },
|
|
871
1042
|
reference: physicalReference
|
|
872
1043
|
};
|
|
873
1044
|
}
|
|
1045
|
+
function inheritanceObject(row, namespace, diagnostics) {
|
|
1046
|
+
const physicalName = text(row.physical_name) ?? `inherited_${text(row.partition_oid) ?? "unknown"}`;
|
|
1047
|
+
const physicalReference = reference("opaque-object", physicalName, text(row.namespace) ?? namespace, "pg_inherits", "inhrelid", row.partition_oid);
|
|
1048
|
+
diagnostics.push(createIntrospectionDiagnostic({
|
|
1049
|
+
severity: "warning",
|
|
1050
|
+
code: "unmodeled-object",
|
|
1051
|
+
message: `PostgreSQL ordinary inheritance ${physicalName} was retained as opaque evidence`,
|
|
1052
|
+
path: ["opaqueObjects", physicalName],
|
|
1053
|
+
physicalReference,
|
|
1054
|
+
remediation: "Inspect the inheritance relationship before using it as migration input."
|
|
1055
|
+
}));
|
|
1056
|
+
return {
|
|
1057
|
+
kind: "opaque-object",
|
|
1058
|
+
id: stableId(`inheritance:${physicalName}`),
|
|
1059
|
+
identitySource: "physical-name",
|
|
1060
|
+
objectKind: "ordinary-inheritance",
|
|
1061
|
+
physicalName,
|
|
1062
|
+
data: {
|
|
1063
|
+
...text(row.parent_oid) === void 0 ? {} : { parentOid: text(row.parent_oid) },
|
|
1064
|
+
...text(row.relkind) === void 0 ? {} : { childRelkind: text(row.relkind) },
|
|
1065
|
+
relispartition: false
|
|
1066
|
+
},
|
|
1067
|
+
reference: physicalReference,
|
|
1068
|
+
provenance: {
|
|
1069
|
+
kind: "catalog",
|
|
1070
|
+
dialect: "postgresql",
|
|
1071
|
+
reference: physicalReference
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
function partitionKeyInfo(value, columns) {
|
|
1076
|
+
const attributes = integerArray(value);
|
|
1077
|
+
const byOrdinal = new Map(columns.map((column) => [column.ordinalPosition, column.physicalName]));
|
|
1078
|
+
const positions = attributes.filter((position) => position > 0);
|
|
1079
|
+
const missingPositions = positions.filter((position) => !byOrdinal.has(position));
|
|
1080
|
+
return {
|
|
1081
|
+
columns: positions.flatMap((position) => {
|
|
1082
|
+
const name = byOrdinal.get(position);
|
|
1083
|
+
return name === void 0 ? [] : [name];
|
|
1084
|
+
}),
|
|
1085
|
+
hasExpression: attributes.some((position) => position === 0),
|
|
1086
|
+
missingPositions
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
874
1089
|
function policyObject(row, namespace, tableByOid, diagnostics) {
|
|
875
1090
|
const physicalName = text(row.physical_name) ?? `policy_${text(row.oid) ?? "unknown"}`;
|
|
876
1091
|
const physicalReference = reference("policy", physicalName, text(row.namespace) ?? namespace, "pg_policy", "oid", row.oid);
|
|
@@ -994,10 +1209,6 @@ function partitionStrategy(value) {
|
|
|
994
1209
|
h: "hash"
|
|
995
1210
|
}[text(value)] ?? "unknown";
|
|
996
1211
|
}
|
|
997
|
-
function partitionKeyColumns(value, columns) {
|
|
998
|
-
const byOrdinal = new Map(columns.map((column) => [column.ordinalPosition, column.physicalName]));
|
|
999
|
-
return integerArray(value).filter((position) => position > 0).map((position) => byOrdinal.get(position) ?? `attnum_${position}`);
|
|
1000
|
-
}
|
|
1001
1212
|
function policyCommand(value) {
|
|
1002
1213
|
return {
|
|
1003
1214
|
"*": "all",
|
|
@@ -1141,6 +1352,7 @@ function column(row, table, namespace, identityOptionValues) {
|
|
|
1141
1352
|
function constraint(row, table, columnsByNumber, tableByOid, namespace, diagnostics, indexReferences) {
|
|
1142
1353
|
const kind = text(row.contype);
|
|
1143
1354
|
const physicalName = text(row.physical_name) ?? `constraint_${text(row.oid) ?? "unknown"}`;
|
|
1355
|
+
const definition = text(row.definition);
|
|
1144
1356
|
const columns = integerArray(row.conkey).map((numberValue) => columnsByNumber.get(numberValue) ?? `attnum_${numberValue}`);
|
|
1145
1357
|
const common = {
|
|
1146
1358
|
id: stableId(physicalName),
|
|
@@ -1160,8 +1372,28 @@ function constraint(row, table, columnsByNumber, tableByOid, namespace, diagnost
|
|
|
1160
1372
|
const backing = backingOid ? indexReferences.get(`pg_class:${backingOid}`) : void 0;
|
|
1161
1373
|
const backingIndex = backing ? {
|
|
1162
1374
|
kind: "index",
|
|
1163
|
-
id: backing.id
|
|
1375
|
+
id: backing.id,
|
|
1376
|
+
owner: {
|
|
1377
|
+
kind: "table",
|
|
1378
|
+
id: table.id
|
|
1379
|
+
}
|
|
1164
1380
|
} : void 0;
|
|
1381
|
+
if (kind === "x" || kind === "c" && (definition === void 0 || definition.trim() === "")) {
|
|
1382
|
+
diagnostics.push(createIntrospectionDiagnostic({
|
|
1383
|
+
severity: "warning",
|
|
1384
|
+
code: "unmodeled-object",
|
|
1385
|
+
message: kind === "x" ? `PostgreSQL exclusion constraint ${physicalName} was retained as opaque evidence` : `PostgreSQL check constraint ${physicalName} has no recoverable definition`,
|
|
1386
|
+
path: [
|
|
1387
|
+
"tables",
|
|
1388
|
+
table.physicalName,
|
|
1389
|
+
"constraints",
|
|
1390
|
+
physicalName
|
|
1391
|
+
],
|
|
1392
|
+
physicalReference: reference("opaque-object", physicalName, namespace, "pg_constraint", "oid", row.oid),
|
|
1393
|
+
remediation: "Inspect the opaque constraint before using it as migration input."
|
|
1394
|
+
}));
|
|
1395
|
+
return opaqueConstraint(row, table, namespace, definition);
|
|
1396
|
+
}
|
|
1165
1397
|
if (kind === "p") return {
|
|
1166
1398
|
kind: "primary-key",
|
|
1167
1399
|
...common,
|
|
@@ -1178,9 +1410,23 @@ function constraint(row, table, columnsByNumber, tableByOid, namespace, diagnost
|
|
|
1178
1410
|
if (kind === "c") return {
|
|
1179
1411
|
kind: "check",
|
|
1180
1412
|
...common,
|
|
1181
|
-
expression: sql(
|
|
1413
|
+
expression: sql(definition, namespace, table, physicalName)
|
|
1182
1414
|
};
|
|
1183
|
-
if (kind !== "f")
|
|
1415
|
+
if (kind !== "f") {
|
|
1416
|
+
diagnostics.push(createIntrospectionDiagnostic({
|
|
1417
|
+
severity: "warning",
|
|
1418
|
+
code: "unmodeled-object",
|
|
1419
|
+
message: `PostgreSQL constraint ${physicalName} (${kind ?? "unknown"}) was retained as opaque evidence`,
|
|
1420
|
+
path: [
|
|
1421
|
+
"tables",
|
|
1422
|
+
table.physicalName,
|
|
1423
|
+
"constraints",
|
|
1424
|
+
physicalName
|
|
1425
|
+
],
|
|
1426
|
+
remediation: "Inspect the opaque constraint before using it as migration input."
|
|
1427
|
+
}));
|
|
1428
|
+
return opaqueConstraint(row, table, namespace, definition);
|
|
1429
|
+
}
|
|
1184
1430
|
const targetTable = tableByOid.get(text(row.target_table_oid));
|
|
1185
1431
|
if (!targetTable) {
|
|
1186
1432
|
diagnostics.push(createIntrospectionDiagnostic({
|
|
@@ -1212,7 +1458,32 @@ function constraint(row, table, columnsByNumber, tableByOid, namespace, diagnost
|
|
|
1212
1458
|
match: matchType(row.confmatchtype)
|
|
1213
1459
|
};
|
|
1214
1460
|
}
|
|
1215
|
-
function
|
|
1461
|
+
function opaqueConstraint(row, table, namespace, definition) {
|
|
1462
|
+
const physicalName = text(row.physical_name) ?? `constraint_${text(row.oid) ?? "unknown"}`;
|
|
1463
|
+
const physicalReference = reference("opaque-object", physicalName, namespace, "pg_constraint", "oid", row.oid);
|
|
1464
|
+
const data = {
|
|
1465
|
+
table: table.physicalName,
|
|
1466
|
+
constraintType: text(row.contype) ?? "unknown",
|
|
1467
|
+
...text(row.conkey) === void 0 ? {} : { keyAttributes: text(row.conkey) },
|
|
1468
|
+
...text(row.backing_index_oid) === void 0 ? {} : { backingIndexOid: text(row.backing_index_oid) }
|
|
1469
|
+
};
|
|
1470
|
+
return {
|
|
1471
|
+
kind: "opaque-object",
|
|
1472
|
+
id: stableId(`constraint:${table.physicalName}:${physicalName}`),
|
|
1473
|
+
identitySource: "physical-name",
|
|
1474
|
+
objectKind: text(row.contype) === "x" ? "exclusion-constraint" : "constraint",
|
|
1475
|
+
physicalName,
|
|
1476
|
+
data,
|
|
1477
|
+
...definition === void 0 ? {} : { sql: sql(definition, namespace, table, physicalName) },
|
|
1478
|
+
reference: physicalReference,
|
|
1479
|
+
provenance: {
|
|
1480
|
+
kind: "catalog",
|
|
1481
|
+
dialect: "postgresql",
|
|
1482
|
+
reference: physicalReference
|
|
1483
|
+
}
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
function mapIndexes(rows, table, columnsByNumber, namespace, diagnostics, opaqueObjects) {
|
|
1216
1487
|
const grouped = /* @__PURE__ */ new Map();
|
|
1217
1488
|
for (const row of rows) {
|
|
1218
1489
|
const key = text(row.index_oid) ?? text(row.physical_name) ?? "unknown";
|
|
@@ -1227,6 +1498,7 @@ function mapIndexes(rows, table, columnsByNumber, namespace) {
|
|
|
1227
1498
|
const keyCount = number(first.indnkeyatts) ?? indexRows.length;
|
|
1228
1499
|
const terms = [];
|
|
1229
1500
|
const includedColumns = [];
|
|
1501
|
+
let unavailableTerm = false;
|
|
1230
1502
|
for (const row of orderedRows) {
|
|
1231
1503
|
const position = number(row.position) ?? 0;
|
|
1232
1504
|
const attnum = number(row.attnum) ?? 0;
|
|
@@ -1235,6 +1507,25 @@ function mapIndexes(rows, table, columnsByNumber, namespace) {
|
|
|
1235
1507
|
if (columnName) includedColumns.push(columnName);
|
|
1236
1508
|
continue;
|
|
1237
1509
|
}
|
|
1510
|
+
const termDefinition = text(row.term_definition);
|
|
1511
|
+
if (!columnName && (termDefinition === void 0 || termDefinition.trim() === "")) {
|
|
1512
|
+
unavailableTerm = true;
|
|
1513
|
+
diagnostics.push(createIntrospectionDiagnostic({
|
|
1514
|
+
severity: "warning",
|
|
1515
|
+
code: "unmodeled-object",
|
|
1516
|
+
message: `PostgreSQL index ${physicalName} has an expression term with no recoverable definition`,
|
|
1517
|
+
path: [
|
|
1518
|
+
table.physicalName,
|
|
1519
|
+
"indexes",
|
|
1520
|
+
physicalName,
|
|
1521
|
+
"terms",
|
|
1522
|
+
position
|
|
1523
|
+
],
|
|
1524
|
+
physicalReference: reference("index", physicalName, namespace, "pg_class", "oid", first.index_oid),
|
|
1525
|
+
remediation: "Inspect the opaque index record before using it as migration input."
|
|
1526
|
+
}));
|
|
1527
|
+
continue;
|
|
1528
|
+
}
|
|
1238
1529
|
terms.push(columnName ? {
|
|
1239
1530
|
kind: "column",
|
|
1240
1531
|
column: columnName,
|
|
@@ -1243,12 +1534,16 @@ function mapIndexes(rows, table, columnsByNumber, namespace) {
|
|
|
1243
1534
|
...text(row.operator_class) === void 0 ? {} : { operatorClass: text(row.operator_class) }
|
|
1244
1535
|
} : {
|
|
1245
1536
|
kind: "expression",
|
|
1246
|
-
expression: sql(
|
|
1537
|
+
expression: sql(termDefinition, namespace, table, physicalName),
|
|
1247
1538
|
position,
|
|
1248
1539
|
...indexTermOptions(row, text(first.method)),
|
|
1249
1540
|
...text(row.operator_class) === void 0 ? {} : { operatorClass: text(row.operator_class) }
|
|
1250
1541
|
});
|
|
1251
1542
|
}
|
|
1543
|
+
if (unavailableTerm) {
|
|
1544
|
+
opaqueObjects.push(opaqueIndex(indexRows, table, namespace));
|
|
1545
|
+
return;
|
|
1546
|
+
}
|
|
1252
1547
|
return {
|
|
1253
1548
|
kind: "index",
|
|
1254
1549
|
id: stableId(physicalName),
|
|
@@ -1266,7 +1561,30 @@ function mapIndexes(rows, table, columnsByNumber, namespace) {
|
|
|
1266
1561
|
} : void 0,
|
|
1267
1562
|
reference: reference("index", physicalName, namespace, "pg_class", "oid", first.index_oid)
|
|
1268
1563
|
};
|
|
1269
|
-
});
|
|
1564
|
+
}).filter((value) => value !== void 0);
|
|
1565
|
+
}
|
|
1566
|
+
function opaqueIndex(rows, table, namespace) {
|
|
1567
|
+
const first = rows[0];
|
|
1568
|
+
const physicalName = text(first.physical_name) ?? `index_${text(first.index_oid) ?? "unknown"}`;
|
|
1569
|
+
const physicalReference = reference("opaque-object", physicalName, namespace, "pg_class", "oid", first.index_oid);
|
|
1570
|
+
return {
|
|
1571
|
+
kind: "opaque-object",
|
|
1572
|
+
id: stableId(`index:${table.physicalName}:${physicalName}`),
|
|
1573
|
+
identitySource: "physical-name",
|
|
1574
|
+
objectKind: "index",
|
|
1575
|
+
physicalName,
|
|
1576
|
+
data: {
|
|
1577
|
+
table: table.physicalName,
|
|
1578
|
+
reason: "term-definition-unavailable",
|
|
1579
|
+
...text(first.index_oid) === void 0 ? {} : { indexOid: text(first.index_oid) }
|
|
1580
|
+
},
|
|
1581
|
+
reference: physicalReference,
|
|
1582
|
+
provenance: {
|
|
1583
|
+
kind: "catalog",
|
|
1584
|
+
dialect: "postgresql",
|
|
1585
|
+
reference: physicalReference
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1270
1588
|
}
|
|
1271
1589
|
function mapMetadataRows(rows, namespace, tables, views, sequences, enums, domains, collations, routines, triggers, policies, extensions, deferredObjects, opaqueObjects, indexReferences, relationReferences, diagnostics) {
|
|
1272
1590
|
const targets = /* @__PURE__ */ new Map();
|
|
@@ -1300,7 +1618,8 @@ function mapMetadataRows(rows, namespace, tables, views, sequences, enums, domai
|
|
|
1300
1618
|
}, opaque.physicalName, opaque.reference);
|
|
1301
1619
|
for (const index of indexReferences.values()) if (index.reference?.catalog !== void 0) add("pg_class", index.reference.catalog.value, {
|
|
1302
1620
|
kind: "index",
|
|
1303
|
-
id: index.id
|
|
1621
|
+
id: index.id,
|
|
1622
|
+
...index.owner === void 0 ? {} : { owner: index.owner }
|
|
1304
1623
|
}, index.physicalName, index.reference);
|
|
1305
1624
|
for (const enumObject of enums) if (enumObject.reference?.catalog !== void 0) add("pg_type", enumObject.reference.catalog.value, {
|
|
1306
1625
|
kind: "enum",
|
|
@@ -1335,7 +1654,11 @@ function mapMetadataRows(rows, namespace, tables, views, sequences, enums, domai
|
|
|
1335
1654
|
for (const table of tables) for (const constraint of table.constraints) if (constraint.reference?.catalog !== void 0) targets.set(metadataKey("pg_constraint", constraint.reference.catalog.value, 0), {
|
|
1336
1655
|
object: {
|
|
1337
1656
|
kind: "constraint",
|
|
1338
|
-
id: constraint.id
|
|
1657
|
+
id: constraint.id,
|
|
1658
|
+
owner: {
|
|
1659
|
+
kind: "table",
|
|
1660
|
+
id: table.id
|
|
1661
|
+
}
|
|
1339
1662
|
},
|
|
1340
1663
|
reference: constraint.reference,
|
|
1341
1664
|
physicalName: constraint.physicalName ?? constraint.id
|
|
@@ -1343,7 +1666,11 @@ function mapMetadataRows(rows, namespace, tables, views, sequences, enums, domai
|
|
|
1343
1666
|
for (const domain of domains) for (const constraint of domain.constraints ?? []) if (constraint.reference?.catalog !== void 0) targets.set(metadataKey("pg_constraint", constraint.reference.catalog.value, 0), {
|
|
1344
1667
|
object: {
|
|
1345
1668
|
kind: "constraint",
|
|
1346
|
-
id: constraint.id
|
|
1669
|
+
id: constraint.id,
|
|
1670
|
+
owner: {
|
|
1671
|
+
kind: "domain",
|
|
1672
|
+
id: domain.id
|
|
1673
|
+
}
|
|
1347
1674
|
},
|
|
1348
1675
|
reference: constraint.reference,
|
|
1349
1676
|
physicalName: constraint.physicalName ?? constraint.id
|
|
@@ -1386,7 +1713,7 @@ function mapMetadataRows(rows, namespace, tables, views, sequences, enums, domai
|
|
|
1386
1713
|
const description = text(row.description);
|
|
1387
1714
|
if (description !== void 0) comments.push({
|
|
1388
1715
|
kind: "comment",
|
|
1389
|
-
id:
|
|
1716
|
+
id: metadataId(target.object, "comment"),
|
|
1390
1717
|
object: target.object,
|
|
1391
1718
|
text: description,
|
|
1392
1719
|
reference: target.reference,
|
|
@@ -1399,7 +1726,7 @@ function mapMetadataRows(rows, namespace, tables, views, sequences, enums, domai
|
|
|
1399
1726
|
const owner = text(row.owner);
|
|
1400
1727
|
if (owner !== void 0) ownership.push({
|
|
1401
1728
|
kind: "ownership",
|
|
1402
|
-
id:
|
|
1729
|
+
id: metadataId(target.object, "ownership"),
|
|
1403
1730
|
object: target.object,
|
|
1404
1731
|
owner,
|
|
1405
1732
|
reference: target.reference,
|
|
@@ -1422,7 +1749,11 @@ function addNestedColumns(targets, relation, owner, namespace) {
|
|
|
1422
1749
|
for (const column of owner.columns) targets.set(metadataKey(relation, tableOid, column.ordinalPosition), {
|
|
1423
1750
|
object: {
|
|
1424
1751
|
kind: "column",
|
|
1425
|
-
id: column.id
|
|
1752
|
+
id: column.id,
|
|
1753
|
+
owner: {
|
|
1754
|
+
kind: owner.kind,
|
|
1755
|
+
id: owner.id
|
|
1756
|
+
}
|
|
1426
1757
|
},
|
|
1427
1758
|
reference: column.reference ?? reference("column", column.physicalName, namespace, "pg_attribute", "attrelid", tableOid),
|
|
1428
1759
|
physicalName: column.physicalName
|
|
@@ -1431,6 +1762,10 @@ function addNestedColumns(targets, relation, owner, namespace) {
|
|
|
1431
1762
|
function metadataKey(relation, oid, subid) {
|
|
1432
1763
|
return `${relation}:${text(oid) ?? "unknown"}:${number(subid) ?? 0}`;
|
|
1433
1764
|
}
|
|
1765
|
+
function metadataId(object, suffix) {
|
|
1766
|
+
const owner = object.owner;
|
|
1767
|
+
return stableId(`${owner === void 0 ? "" : `${owner.kind}_${owner.id}_`}${object.kind}_${object.id}_${suffix}`);
|
|
1768
|
+
}
|
|
1434
1769
|
function indexTermOptions(row, method) {
|
|
1435
1770
|
const option = number(row.indoption);
|
|
1436
1771
|
if (method !== "btree" || option === void 0) return {};
|
|
@@ -1530,9 +1865,9 @@ function booleanOption(options, name) {
|
|
|
1530
1865
|
}
|
|
1531
1866
|
function integerArray(value) {
|
|
1532
1867
|
if (Array.isArray(value)) return value.map((item) => number(item) ?? 0);
|
|
1533
|
-
const parsed = text(value)?.replace(/[{}]/g, "").trim();
|
|
1868
|
+
const parsed = text(value)?.replace(/^\[[^\]]+\]=/, "").replace(/[{}]/g, "").trim();
|
|
1534
1869
|
if (!parsed) return [];
|
|
1535
|
-
return parsed.split(
|
|
1870
|
+
return parsed.split(/[\s,]+/).map((item) => number(item.trim())).filter((item) => item !== void 0);
|
|
1536
1871
|
}
|
|
1537
1872
|
function referentialAction(value) {
|
|
1538
1873
|
return {
|
|
@@ -1551,4 +1886,4 @@ function matchType(value) {
|
|
|
1551
1886
|
}[text(value)];
|
|
1552
1887
|
}
|
|
1553
1888
|
//#endregion
|
|
1554
|
-
export { postgresCollationsQuery, postgresColumnsQuery, postgresConstraintsQuery, postgresDomainConstraintsQuery, postgresDomainsQuery, postgresEnumsQuery, postgresExtensionsQuery, postgresIdentitiesQuery, postgresIndexesQuery, postgresMetadataQuery, postgresPartitionsQuery, postgresPoliciesQuery, postgresRelationsQuery, postgresRoutineParametersQuery, postgresRoutinesQuery, postgresSequencesQuery, postgresServerQuery, postgresTriggersQuery, postgresViewsQuery, readCatalog };
|
|
1889
|
+
export { postgresCollationsQuery, postgresColumnsQuery, postgresConstraintsQuery, postgresConstraintsQueryWithoutNullsNotDistinct, postgresDomainConstraintsQuery, postgresDomainsQuery, postgresEnumsQuery, postgresExtensionsQuery, postgresIdentitiesQuery, postgresIndexesQuery, postgresMetadataQuery, postgresPartitionsQuery, postgresPoliciesQuery, postgresRelationsQuery, postgresRoutineParametersQuery, postgresRoutinesQuery, postgresSequencesQuery, postgresServerQuery, postgresTriggersQuery, postgresViewsQuery, readCatalog };
|