@prisma-next/adapter-postgres 0.15.0-dev.13 → 0.15.0-dev.3
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/{adapter-Bh8GA6sC.mjs → adapter-CssyjkaR.mjs} +2 -2
- package/dist/{adapter-Bh8GA6sC.mjs.map → adapter-CssyjkaR.mjs.map} +1 -1
- package/dist/adapter.mjs +1 -1
- package/dist/{control-adapter-aFfSI2bK.mjs → control-adapter-w2BFxQ--.mjs} +60 -118
- package/dist/control-adapter-w2BFxQ--.mjs.map +1 -0
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +23 -23
- package/src/core/control-adapter.ts +60 -130
- package/dist/control-adapter-aFfSI2bK.mjs.map +0 -1
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import type { SqlControlAdapter } from '@prisma-next/family-sql/control-adapter';
|
|
8
8
|
import { parseContractMarkerRow } from '@prisma-next/family-sql/verify';
|
|
9
9
|
import type { CodecLookup, CodecRegistry } from '@prisma-next/framework-components/codec';
|
|
10
|
-
import { APP_SPACE_ID
|
|
10
|
+
import { APP_SPACE_ID } from '@prisma-next/framework-components/control';
|
|
11
11
|
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
12
12
|
import { ledgerOriginFromStored } from '@prisma-next/migration-tools/ledger-origin';
|
|
13
13
|
import { REFERENTIAL_ACTION_SQL } from '@prisma-next/sql-contract/referential-action-sql';
|
|
@@ -36,7 +36,6 @@ import type {
|
|
|
36
36
|
SqlReferentialAction,
|
|
37
37
|
SqlUniqueIRInput,
|
|
38
38
|
} from '@prisma-next/sql-schema-ir/types';
|
|
39
|
-
import { RelationalSchemaNodeKind } from '@prisma-next/sql-schema-ir/types';
|
|
40
39
|
import {
|
|
41
40
|
buildControlTableBootstrapQueries,
|
|
42
41
|
buildSignMarkerBootstrapQueries,
|
|
@@ -67,7 +66,6 @@ import {
|
|
|
67
66
|
PostgresNativeEnumSchemaNode,
|
|
68
67
|
PostgresPolicySchemaNode,
|
|
69
68
|
PostgresRoleSchemaNode,
|
|
70
|
-
PostgresSchemaNodeKind,
|
|
71
69
|
PostgresTableSchemaNode,
|
|
72
70
|
} from '@prisma-next/target-postgres/types';
|
|
73
71
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
@@ -739,13 +737,7 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
739
737
|
ORDER BY c.table_name, c.ordinal_position`,
|
|
740
738
|
[schema],
|
|
741
739
|
);
|
|
742
|
-
// Query all primary keys for all tables in schema
|
|
743
|
-
// information_schema: `information_schema.table_constraints` hides
|
|
744
|
-
// constraints on tables where the connecting role's only privilege is
|
|
745
|
-
// SELECT (its filter grants visibility for INSERT/UPDATE/DELETE/TRUNCATE/
|
|
746
|
-
// REFERENCES/TRIGGER — not SELECT), so a SELECT-only table introspects
|
|
747
|
-
// with all its columns but zero constraints and verify reports every
|
|
748
|
-
// declared constraint as missing. pg_catalog is not privilege-filtered.
|
|
740
|
+
// Query all primary keys for all tables in schema
|
|
749
741
|
const pkResult = await driver.query<{
|
|
750
742
|
table_name: string;
|
|
751
743
|
constraint_name: string;
|
|
@@ -753,29 +745,24 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
753
745
|
ordinal_position: number;
|
|
754
746
|
}>(
|
|
755
747
|
`SELECT
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
FROM
|
|
761
|
-
JOIN
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
AND
|
|
767
|
-
|
|
768
|
-
AND con.contype = 'p'
|
|
769
|
-
ORDER BY cl.relname, k.ord`,
|
|
748
|
+
tc.table_name,
|
|
749
|
+
tc.constraint_name,
|
|
750
|
+
kcu.column_name,
|
|
751
|
+
kcu.ordinal_position
|
|
752
|
+
FROM information_schema.table_constraints tc
|
|
753
|
+
JOIN information_schema.key_column_usage kcu
|
|
754
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
755
|
+
AND tc.table_schema = kcu.table_schema
|
|
756
|
+
AND tc.table_name = kcu.table_name
|
|
757
|
+
WHERE tc.table_schema = $1
|
|
758
|
+
AND tc.constraint_type = 'PRIMARY KEY'
|
|
759
|
+
ORDER BY tc.table_name, kcu.ordinal_position`,
|
|
770
760
|
[schema],
|
|
771
761
|
);
|
|
772
|
-
// Query all foreign keys for all tables in schema, including referential
|
|
773
|
-
//
|
|
774
|
-
// information_schema
|
|
775
|
-
//
|
|
776
|
-
// round-trip in declared order. The referential-action CASEs mirror
|
|
777
|
-
// pg_constraint's confdeltype/confupdtype encoding and produce the same
|
|
778
|
-
// rule strings information_schema.referential_constraints reports.
|
|
762
|
+
// Query all foreign keys for all tables in schema, including referential actions.
|
|
763
|
+
// Uses pg_catalog for correct positional pairing of composite FK columns
|
|
764
|
+
// (information_schema.constraint_column_usage lacks ordinal_position,
|
|
765
|
+
// which causes Cartesian products for multi-column FKs).
|
|
779
766
|
const fkResult = await driver.query<{
|
|
780
767
|
table_name: string;
|
|
781
768
|
constraint_name: string;
|
|
@@ -788,48 +775,41 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
788
775
|
update_rule: string;
|
|
789
776
|
}>(
|
|
790
777
|
`SELECT
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
778
|
+
tc.table_name,
|
|
779
|
+
tc.constraint_name,
|
|
780
|
+
kcu.column_name,
|
|
781
|
+
kcu.ordinal_position,
|
|
795
782
|
ref_ns.nspname AS referenced_table_schema,
|
|
796
783
|
ref_cl.relname AS referenced_table_name,
|
|
797
784
|
ref_att.attname AS referenced_column_name,
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
WHEN 'd' THEN 'SET DEFAULT'
|
|
811
|
-
END AS update_rule
|
|
812
|
-
FROM pg_catalog.pg_constraint con
|
|
813
|
-
JOIN pg_catalog.pg_class cl ON cl.oid = con.conrelid
|
|
814
|
-
JOIN pg_catalog.pg_namespace ns ON ns.oid = cl.relnamespace
|
|
815
|
-
JOIN LATERAL unnest(con.conkey) WITH ORDINALITY AS k(attnum, ord) ON true
|
|
816
|
-
JOIN pg_catalog.pg_attribute a
|
|
817
|
-
ON a.attrelid = con.conrelid
|
|
818
|
-
AND a.attnum = k.attnum
|
|
785
|
+
rc.delete_rule,
|
|
786
|
+
rc.update_rule
|
|
787
|
+
FROM information_schema.table_constraints tc
|
|
788
|
+
JOIN information_schema.key_column_usage kcu
|
|
789
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
790
|
+
AND tc.table_schema = kcu.table_schema
|
|
791
|
+
AND tc.table_name = kcu.table_name
|
|
792
|
+
JOIN pg_catalog.pg_constraint pgc
|
|
793
|
+
ON pgc.conname = tc.constraint_name
|
|
794
|
+
AND pgc.connamespace = (
|
|
795
|
+
SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = tc.table_schema
|
|
796
|
+
)
|
|
819
797
|
JOIN pg_catalog.pg_class ref_cl
|
|
820
|
-
ON ref_cl.oid =
|
|
798
|
+
ON ref_cl.oid = pgc.confrelid
|
|
821
799
|
JOIN pg_catalog.pg_namespace ref_ns
|
|
822
800
|
ON ref_ns.oid = ref_cl.relnamespace
|
|
823
801
|
JOIN pg_catalog.pg_attribute ref_att
|
|
824
|
-
ON ref_att.attrelid =
|
|
825
|
-
AND ref_att.attnum =
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
802
|
+
ON ref_att.attrelid = pgc.confrelid
|
|
803
|
+
AND ref_att.attnum = pgc.confkey[kcu.ordinal_position]
|
|
804
|
+
JOIN information_schema.referential_constraints rc
|
|
805
|
+
ON rc.constraint_name = tc.constraint_name
|
|
806
|
+
AND rc.constraint_schema = tc.table_schema
|
|
807
|
+
WHERE tc.table_schema = $1
|
|
808
|
+
AND tc.constraint_type = 'FOREIGN KEY'
|
|
809
|
+
ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,
|
|
829
810
|
[schema],
|
|
830
811
|
);
|
|
831
|
-
// Query all unique constraints for all tables in schema (excluding PKs)
|
|
832
|
-
// Reads pg_catalog (see the primary-key query above).
|
|
812
|
+
// Query all unique constraints for all tables in schema (excluding PKs)
|
|
833
813
|
const uniqueResult = await driver.query<{
|
|
834
814
|
table_name: string;
|
|
835
815
|
constraint_name: string;
|
|
@@ -837,20 +817,18 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
837
817
|
ordinal_position: number;
|
|
838
818
|
}>(
|
|
839
819
|
`SELECT
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
FROM
|
|
845
|
-
JOIN
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
AND
|
|
851
|
-
|
|
852
|
-
AND con.contype = 'u'
|
|
853
|
-
ORDER BY cl.relname, con.conname, k.ord`,
|
|
820
|
+
tc.table_name,
|
|
821
|
+
tc.constraint_name,
|
|
822
|
+
kcu.column_name,
|
|
823
|
+
kcu.ordinal_position
|
|
824
|
+
FROM information_schema.table_constraints tc
|
|
825
|
+
JOIN information_schema.key_column_usage kcu
|
|
826
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
827
|
+
AND tc.table_schema = kcu.table_schema
|
|
828
|
+
AND tc.table_name = kcu.table_name
|
|
829
|
+
WHERE tc.table_schema = $1
|
|
830
|
+
AND tc.constraint_type = 'UNIQUE'
|
|
831
|
+
ORDER BY tc.table_name, tc.constraint_name, kcu.ordinal_position`,
|
|
854
832
|
[schema],
|
|
855
833
|
);
|
|
856
834
|
// Query all indexes for all tables in schema (excluding constraints).
|
|
@@ -895,9 +873,10 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
895
873
|
WHERE i.schemaname = $1
|
|
896
874
|
AND NOT EXISTS (
|
|
897
875
|
SELECT 1
|
|
898
|
-
FROM
|
|
899
|
-
WHERE
|
|
900
|
-
AND
|
|
876
|
+
FROM information_schema.table_constraints tc
|
|
877
|
+
WHERE tc.table_schema = $1
|
|
878
|
+
AND tc.table_name = i.tablename
|
|
879
|
+
AND tc.constraint_name = i.indexname
|
|
901
880
|
)
|
|
902
881
|
ORDER BY i.tablename, i.indexname, k.ord`,
|
|
903
882
|
[schema],
|
|
@@ -1033,7 +1012,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
1033
1012
|
? {
|
|
1034
1013
|
columns: primaryKeyColumns,
|
|
1035
1014
|
...(pkRows[0]?.constraint_name ? { name: pkRows[0].constraint_name } : {}),
|
|
1036
|
-
dependsOn: postgresColumnDependsOn(schema, tableName, primaryKeyColumns),
|
|
1037
1015
|
}
|
|
1038
1016
|
: undefined;
|
|
1039
1017
|
|
|
@@ -1076,10 +1054,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
1076
1054
|
name: fk.name,
|
|
1077
1055
|
...ifDefined('onDelete', mapReferentialAction(fk.deleteRule)),
|
|
1078
1056
|
...ifDefined('onUpdate', mapReferentialAction(fk.updateRule)),
|
|
1079
|
-
dependsOn: [
|
|
1080
|
-
postgresTableDependsOn(fk.referencedSchema, fk.referencedTable),
|
|
1081
|
-
...postgresColumnDependsOn(schema, tableName, fk.columns),
|
|
1082
|
-
],
|
|
1083
1057
|
}),
|
|
1084
1058
|
);
|
|
1085
1059
|
|
|
@@ -1104,7 +1078,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
1104
1078
|
const uniques: readonly SqlUniqueIRInput[] = Array.from(uniquesMap.values()).map((uq) => ({
|
|
1105
1079
|
columns: Object.freeze([...uq.columns]) as readonly string[],
|
|
1106
1080
|
name: uq.name,
|
|
1107
|
-
dependsOn: postgresColumnDependsOn(schema, tableName, uq.columns),
|
|
1108
1081
|
}));
|
|
1109
1082
|
|
|
1110
1083
|
// Process indexes
|
|
@@ -1186,7 +1159,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
1186
1159
|
unique: idx.unique,
|
|
1187
1160
|
...(idx.type !== undefined && { type: idx.type }),
|
|
1188
1161
|
...(idx.options !== undefined && { options: idx.options }),
|
|
1189
|
-
dependsOn: postgresColumnDependsOn(schema, tableName, idx.columns),
|
|
1190
1162
|
}),
|
|
1191
1163
|
);
|
|
1192
1164
|
|
|
@@ -1269,10 +1241,6 @@ export class PostgresControlAdapter implements SqlControlAdapter<'postgres'> {
|
|
|
1269
1241
|
...(row.qual !== null ? { using: row.qual } : {}),
|
|
1270
1242
|
...(row.with_check !== null ? { withCheck: row.with_check } : {}),
|
|
1271
1243
|
permissive,
|
|
1272
|
-
dependsOn: [
|
|
1273
|
-
postgresTableDependsOn(row.schemaname, row.tablename),
|
|
1274
|
-
...policyRoles.map(postgresRoleDependsOn),
|
|
1275
|
-
],
|
|
1276
1244
|
});
|
|
1277
1245
|
const list = policiesByTable.get(row.tablename) ?? [];
|
|
1278
1246
|
list.push(policy);
|
|
@@ -1534,44 +1502,6 @@ function mapReferentialAction(rule: string): SqlReferentialAction | undefined {
|
|
|
1534
1502
|
return mapped;
|
|
1535
1503
|
}
|
|
1536
1504
|
|
|
1537
|
-
/**
|
|
1538
|
-
* A FK/policy dependency chain, mirroring the shape the expected-side
|
|
1539
|
-
* derivation stamps (`contractToPostgresDatabaseSchemaNode`): the database
|
|
1540
|
-
* root's fixed sentinel id, then the namespace, then the table.
|
|
1541
|
-
*/
|
|
1542
|
-
function postgresTableDependsOn(namespaceId: string, tableName: string): SchemaNodeRef {
|
|
1543
|
-
return [
|
|
1544
|
-
{ nodeKind: PostgresSchemaNodeKind.database, id: 'database' },
|
|
1545
|
-
{ nodeKind: PostgresSchemaNodeKind.namespace, id: namespaceId },
|
|
1546
|
-
{ nodeKind: PostgresSchemaNodeKind.table, id: tableName },
|
|
1547
|
-
];
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
|
-
/** A policy's dependency chain onto one of the roles it grants to. */
|
|
1551
|
-
function postgresRoleDependsOn(role: string): SchemaNodeRef {
|
|
1552
|
-
return [
|
|
1553
|
-
{ nodeKind: PostgresSchemaNodeKind.database, id: 'database' },
|
|
1554
|
-
{ nodeKind: PostgresSchemaNodeKind.role, id: role },
|
|
1555
|
-
];
|
|
1556
|
-
}
|
|
1557
|
-
|
|
1558
|
-
/**
|
|
1559
|
-
* The chains from a table-child object (foreign key, index, unique, primary
|
|
1560
|
-
* key) to each of the own columns it is built on — the introspection-side
|
|
1561
|
-
* mirror of `contractToPostgresDatabaseSchemaNode`'s `columnDependsOn`. An
|
|
1562
|
-
* object is dropped before the columns it covers.
|
|
1563
|
-
*/
|
|
1564
|
-
function postgresColumnDependsOn(
|
|
1565
|
-
namespaceId: string,
|
|
1566
|
-
tableName: string,
|
|
1567
|
-
columns: readonly string[],
|
|
1568
|
-
): SchemaNodeRef[] {
|
|
1569
|
-
return columns.map((column) => [
|
|
1570
|
-
...postgresTableDependsOn(namespaceId, tableName),
|
|
1571
|
-
{ nodeKind: RelationalSchemaNodeKind.column, id: `column:${column}` },
|
|
1572
|
-
]);
|
|
1573
|
-
}
|
|
1574
|
-
|
|
1575
1505
|
/**
|
|
1576
1506
|
* Groups an array of objects by a specified key.
|
|
1577
1507
|
* Returns a Map for O(1) lookup by group key.
|