@prisma-next/target-postgres 0.14.0-dev.8 → 0.14.0-dev.81
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/authoring-ChmUI_tC.mjs +674 -0
- package/dist/authoring-ChmUI_tC.mjs.map +1 -0
- package/dist/canonicalize-D1F4vUnP.d.mts +48 -0
- package/dist/canonicalize-D1F4vUnP.d.mts.map +1 -0
- package/dist/{codec-ids-CnXu9Qy3.d.mts → codec-ids-BzrFF-I4.d.mts} +3 -2
- package/dist/codec-ids-BzrFF-I4.d.mts.map +1 -0
- package/dist/{codec-ids-BvytN2P8.mjs → codec-ids-C_-Hj6bL.mjs} +3 -2
- package/dist/codec-ids-C_-Hj6bL.mjs.map +1 -0
- package/dist/codec-ids.d.mts +2 -2
- package/dist/codec-ids.mjs +2 -2
- package/dist/{codec-types-DHCkwPKE.d.mts → codec-types-BiIWziRO.d.mts} +3 -2
- package/dist/codec-types-BiIWziRO.d.mts.map +1 -0
- package/dist/codec-types.d.mts +1 -1
- package/dist/codecs-BemGS69L.mjs +927 -0
- package/dist/codecs-BemGS69L.mjs.map +1 -0
- package/dist/{codecs--0A5_4Bq.d.mts → codecs-Cm-nS4mQ.d.mts} +111 -4
- package/dist/codecs-Cm-nS4mQ.d.mts.map +1 -0
- package/dist/codecs.d.mts +2 -2
- package/dist/codecs.mjs +3 -757
- package/dist/codecs.mjs.map +1 -1
- package/dist/contract-free.d.mts +33 -3
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +23 -7
- package/dist/contract-free.mjs.map +1 -1
- package/dist/control-policy-BfQLCrha.mjs +1285 -0
- package/dist/control-policy-BfQLCrha.mjs.map +1 -0
- package/dist/control.d.mts +2 -2
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +866 -36
- package/dist/control.mjs.map +1 -1
- package/dist/data-transform-BOWpliq8.mjs.map +1 -1
- package/dist/{data-transform-DDgWdB5o.d.mts → data-transform-DPzwBMhW.d.mts} +3 -3
- package/dist/{data-transform-DDgWdB5o.d.mts.map → data-transform-DPzwBMhW.d.mts.map} +1 -1
- package/dist/data-transform.d.mts +1 -1
- package/dist/{ddl-QDyOSeLc.mjs → ddl-eBZav_MS.mjs} +128 -6
- package/dist/ddl-eBZav_MS.mjs.map +1 -0
- package/dist/ddl.d.mts +3 -2
- package/dist/ddl.mjs +2 -2
- package/dist/default-normalizer.d.mts +1 -1
- package/dist/default-normalizer.d.mts.map +1 -1
- package/dist/default-normalizer.mjs +247 -1
- package/dist/default-normalizer.mjs.map +1 -0
- package/dist/descriptor-meta-DAwRBZpA.mjs +23 -0
- package/dist/descriptor-meta-DAwRBZpA.mjs.map +1 -0
- package/dist/descriptor-meta-runtime-UwYdV8fD.mjs +12 -0
- package/dist/descriptor-meta-runtime-UwYdV8fD.mjs.map +1 -0
- package/dist/diff-database-schema-jsEOfSYT.mjs +305 -0
- package/dist/diff-database-schema-jsEOfSYT.mjs.map +1 -0
- package/dist/diff-database-schema.d.mts +46 -0
- package/dist/diff-database-schema.d.mts.map +1 -0
- package/dist/diff-database-schema.mjs +2 -0
- package/dist/errors-DO-w0EUS.mjs +35 -0
- package/dist/errors-DO-w0EUS.mjs.map +1 -0
- package/dist/errors.d.mts +11 -9
- package/dist/errors.d.mts.map +1 -1
- package/dist/errors.mjs +1 -1
- package/dist/issue-planner.d.mts +35 -11
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +2 -2
- package/dist/migration.d.mts +5 -5
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +4 -4
- package/dist/namespace-ids-xtp_ZY86.mjs +7 -0
- package/dist/namespace-ids-xtp_ZY86.mjs.map +1 -0
- package/dist/native-type-normalizer.mjs +37 -1
- package/dist/native-type-normalizer.mjs.map +1 -0
- package/dist/nodes-DJC5B8Id.mjs +192 -0
- package/dist/nodes-DJC5B8Id.mjs.map +1 -0
- package/dist/nodes-Dv5eCSq9.d.mts +170 -0
- package/dist/nodes-Dv5eCSq9.d.mts.map +1 -0
- package/dist/{op-factory-call-DmQEc3XV.d.mts → op-factory-call-Bn9zDx4_.d.mts} +114 -15
- package/dist/op-factory-call-Bn9zDx4_.d.mts.map +1 -0
- package/dist/{op-factory-call-D_p5vxwt.mjs → op-factory-call-Dwsb1xzl.mjs} +469 -32
- package/dist/op-factory-call-Dwsb1xzl.mjs.map +1 -0
- package/dist/op-factory-call.d.mts +2 -2
- package/dist/op-factory-call.mjs +2 -2
- package/dist/pack.d.mts +321 -3
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/planner-ChCtpEGe.mjs +390 -0
- package/dist/planner-ChCtpEGe.mjs.map +1 -0
- package/dist/{planner-ddl-builders-B2wOwLqI.mjs → planner-ddl-builders-BKlmGDJl.mjs} +17 -28
- package/dist/planner-ddl-builders-BKlmGDJl.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +4 -6
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +2 -2
- package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -1
- package/dist/planner-identity-values.d.mts +8 -2
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +2 -2
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts → planner-produced-postgres-migration-BEY1T0Xm.d.mts} +4 -4
- package/dist/{planner-produced-postgres-migration-QqHa2C2l.d.mts.map → planner-produced-postgres-migration-BEY1T0Xm.d.mts.map} +1 -1
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs → planner-produced-postgres-migration-Bb16yHNX.mjs} +3 -3
- package/dist/{planner-produced-postgres-migration-Cji5vxUf.mjs.map → planner-produced-postgres-migration-Bb16yHNX.mjs.map} +1 -1
- package/dist/planner-produced-postgres-migration.d.mts +1 -1
- package/dist/planner-produced-postgres-migration.mjs +1 -1
- package/dist/{planner-sql-checks-jqUUGyQR.mjs → planner-sql-checks-Cx0ATsPc.mjs} +5 -5
- package/dist/{planner-sql-checks-jqUUGyQR.mjs.map → planner-sql-checks-Cx0ATsPc.mjs.map} +1 -1
- package/dist/planner-sql-checks.d.mts +2 -2
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +1 -1
- package/dist/{planner-target-details-CIY6tLeo.d.mts → planner-target-details-HkP4RrRO.d.mts} +2 -2
- package/dist/planner-target-details-HkP4RrRO.d.mts.map +1 -0
- package/dist/planner-target-details.d.mts +1 -1
- package/dist/planner.d.mts +72 -17
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +3 -2
- package/dist/{postgres-contract-serializer-k3TAcPMY.mjs → postgres-contract-view-BiDhl5Ez.mjs} +45 -41
- package/dist/postgres-contract-view-BiDhl5Ez.mjs.map +1 -0
- package/dist/postgres-contract-view-C9j5cqP0.d.mts +34 -0
- package/dist/postgres-contract-view-C9j5cqP0.d.mts.map +1 -0
- package/dist/postgres-database-schema-node-CJv5bfbs.d.mts +262 -0
- package/dist/postgres-database-schema-node-CJv5bfbs.d.mts.map +1 -0
- package/dist/{postgres-migration-B5jKrXv3.mjs → postgres-migration-Cj5Tpj1a.mjs} +78 -45
- package/dist/postgres-migration-Cj5Tpj1a.mjs.map +1 -0
- package/dist/{postgres-migration-Y4YBJqkS.d.mts → postgres-migration-DbckK1su.d.mts} +58 -9
- package/dist/postgres-migration-DbckK1su.d.mts.map +1 -0
- package/dist/postgres-native-enum-BwVNf0Ku.mjs +45 -0
- package/dist/postgres-native-enum-BwVNf0Ku.mjs.map +1 -0
- package/dist/postgres-rls-policy--CSddvMR.d.mts +52 -0
- package/dist/postgres-rls-policy--CSddvMR.d.mts.map +1 -0
- package/dist/postgres-role-schema-node-Cm-j0ZGM.mjs +190 -0
- package/dist/postgres-role-schema-node-Cm-j0ZGM.mjs.map +1 -0
- package/dist/{postgres-schema-COGZ1ark.mjs → postgres-schema-ChBj22nX.mjs} +200 -11
- package/dist/postgres-schema-ChBj22nX.mjs.map +1 -0
- package/dist/postgres-schema-DKq6s1P3.d.mts +269 -0
- package/dist/postgres-schema-DKq6s1P3.d.mts.map +1 -0
- package/dist/postgres-table-schema-node-D6LvInCe.mjs +216 -0
- package/dist/postgres-table-schema-node-D6LvInCe.mjs.map +1 -0
- package/dist/render-ops.d.mts +1 -1
- package/dist/{render-typescript-KMgosran.mjs → render-typescript-7yqILcwr.mjs} +45 -16
- package/dist/render-typescript-7yqILcwr.mjs.map +1 -0
- package/dist/render-typescript.mjs +1 -1
- package/dist/resolve-ddl-schema-BCSMHFwl.mjs +22 -0
- package/dist/resolve-ddl-schema-BCSMHFwl.mjs.map +1 -0
- package/dist/rls-canonicalize.d.mts +27 -0
- package/dist/rls-canonicalize.d.mts.map +1 -0
- package/dist/rls-canonicalize.mjs +2 -0
- package/dist/runtime.d.mts +6 -8
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +3 -3
- package/dist/runtime.mjs.map +1 -1
- package/dist/schema-ir-annotations.d.mts +15 -0
- package/dist/schema-ir-annotations.d.mts.map +1 -0
- package/dist/schema-ir-annotations.mjs +2 -0
- package/dist/{sql-utils-DcfMz4MQ.mjs → sql-utils-SU4FDvIV.mjs} +12 -3
- package/dist/{sql-utils-DcfMz4MQ.mjs.map → sql-utils-SU4FDvIV.mjs.map} +1 -1
- package/dist/sql-utils.d.mts +8 -1
- package/dist/sql-utils.d.mts.map +1 -1
- package/dist/sql-utils.mjs +2 -2
- package/dist/types.d.mts +4 -140
- package/dist/types.mjs +5 -2
- package/dist/wire-name-DbQ9-2RC.mjs +104 -0
- package/dist/wire-name-DbQ9-2RC.mjs.map +1 -0
- package/package.json +26 -20
- package/src/contract-free/checks.ts +153 -0
- package/src/contract-free/control-bootstrap.ts +20 -3
- package/src/contract-free/ddl.ts +98 -1
- package/src/core/authoring.ts +726 -2
- package/src/core/codec-helpers.ts +33 -7
- package/src/core/codec-ids.ts +1 -0
- package/src/core/codec-type-map.ts +2 -0
- package/src/core/codecs.ts +193 -12
- package/src/core/ddl/nodes.ts +185 -2
- package/src/core/default-normalizer.ts +122 -2
- package/src/core/descriptor-meta.ts +12 -1
- package/src/core/entity-kinds.ts +41 -0
- package/src/core/errors.ts +14 -12
- package/src/core/migrations/bound-schema.ts +10 -0
- package/src/core/migrations/column-ddl-rendering.ts +117 -0
- package/src/core/migrations/contract-to-postgres-database-schema-node.ts +189 -0
- package/src/core/migrations/control-policy.ts +217 -65
- package/src/core/migrations/diff-database-schema.ts +252 -0
- package/src/core/migrations/issue-planner.ts +817 -656
- package/src/core/migrations/op-factory-call.ts +383 -23
- package/src/core/migrations/operations/columns.ts +24 -12
- package/src/core/migrations/operations/constraints.ts +1 -1
- package/src/core/migrations/operations/data-transform.ts +6 -0
- package/src/core/migrations/operations/dependencies.ts +2 -1
- package/src/core/migrations/operations/native-enum-types.ts +62 -0
- package/src/core/migrations/operations/rls.ts +187 -0
- package/src/core/migrations/operations/shared.ts +0 -30
- package/src/core/migrations/planner-ddl-builders.ts +31 -59
- package/src/core/migrations/planner-identity-values.ts +1 -1
- package/src/core/migrations/planner-recipes.ts +31 -13
- package/src/core/migrations/planner-sql-checks.ts +1 -1
- package/src/core/migrations/planner-strategies.ts +248 -216
- package/src/core/migrations/planner-target-details.ts +3 -1
- package/src/core/migrations/planner.ts +357 -67
- package/src/core/migrations/postgres-migration.ts +118 -86
- package/src/core/migrations/render-typescript.ts +42 -15
- package/src/core/migrations/resolve-ddl-schema.ts +26 -0
- package/src/core/migrations/runner.ts +11 -16
- package/src/core/migrations/verify-postgres-namespaces.ts +46 -31
- package/src/core/namespace-ids.ts +3 -0
- package/src/core/postgres-contract-serializer.ts +46 -71
- package/src/core/postgres-contract-view.ts +48 -0
- package/src/core/postgres-native-enum.ts +61 -0
- package/src/core/postgres-rls-enablement.ts +34 -0
- package/src/core/postgres-rls-policy.ts +64 -0
- package/src/core/postgres-role.ts +59 -0
- package/src/core/postgres-schema-verifier.ts +10 -7
- package/src/core/postgres-schema.ts +85 -15
- package/src/core/postgres-validators.ts +34 -0
- package/src/core/psl-infer/infer-psl-contract.ts +1273 -0
- package/src/core/psl-infer/postgres-default-mapping.ts +16 -0
- package/src/core/psl-infer/postgres-type-map.ts +128 -0
- package/src/core/rls/canonicalize.ts +65 -0
- package/src/core/rls/wire-name.ts +33 -0
- package/src/core/schema-ir/node-storage-coordinate.ts +26 -0
- package/src/core/schema-ir/postgres-database-schema-node.ts +61 -0
- package/src/core/schema-ir/postgres-namespace-schema-node.ts +70 -0
- package/src/core/schema-ir/postgres-native-enum-schema-node.ts +83 -0
- package/src/core/schema-ir/postgres-policy-schema-node.ts +90 -0
- package/src/core/schema-ir/postgres-role-schema-node.ts +65 -0
- package/src/core/schema-ir/postgres-table-schema-node.ts +140 -0
- package/src/core/schema-ir/schema-node-kinds.ts +122 -0
- package/src/core/sql-utils.ts +15 -2
- package/src/exports/codecs.ts +3 -0
- package/src/exports/contract-free.ts +11 -1
- package/src/exports/control.ts +27 -33
- package/src/exports/ddl.ts +8 -0
- package/src/exports/diff-database-schema.ts +7 -0
- package/src/exports/issue-planner.ts +1 -1
- package/src/exports/migration.ts +1 -0
- package/src/exports/op-factory-call.ts +4 -0
- package/src/exports/planner-ddl-builders.ts +0 -2
- package/src/exports/planner-identity-values.ts +4 -1
- package/src/exports/planner.ts +1 -0
- package/src/exports/rls-canonicalize.ts +12 -0
- package/src/exports/runtime.ts +1 -0
- package/src/exports/schema-ir-annotations.ts +1 -0
- package/src/exports/sql-utils.ts +1 -0
- package/src/exports/types.ts +37 -0
- package/dist/codec-ids-BvytN2P8.mjs.map +0 -1
- package/dist/codec-ids-CnXu9Qy3.d.mts.map +0 -1
- package/dist/codec-types-DHCkwPKE.d.mts.map +0 -1
- package/dist/codecs--0A5_4Bq.d.mts.map +0 -1
- package/dist/ddl-QDyOSeLc.mjs.map +0 -1
- package/dist/default-normalizer-DyyCHQWs.mjs +0 -131
- package/dist/default-normalizer-DyyCHQWs.mjs.map +0 -1
- package/dist/descriptor-meta-CpGygXpI.mjs +0 -140
- package/dist/descriptor-meta-CpGygXpI.mjs.map +0 -1
- package/dist/errors-CUk87ByX.mjs +0 -33
- package/dist/errors-CUk87ByX.mjs.map +0 -1
- package/dist/issue-planner-DL6g3CmE.mjs +0 -824
- package/dist/issue-planner-DL6g3CmE.mjs.map +0 -1
- package/dist/native-type-normalizer-Bc9XJzWC.mjs +0 -38
- package/dist/native-type-normalizer-Bc9XJzWC.mjs.map +0 -1
- package/dist/nodes-Bbhs2rwj.mjs +0 -76
- package/dist/nodes-Bbhs2rwj.mjs.map +0 -1
- package/dist/nodes-pLeLgdis.d.mts +0 -67
- package/dist/nodes-pLeLgdis.d.mts.map +0 -1
- package/dist/op-factory-call-D_p5vxwt.mjs.map +0 -1
- package/dist/op-factory-call-DmQEc3XV.d.mts.map +0 -1
- package/dist/planner-Bs_baQax.mjs +0 -324
- package/dist/planner-Bs_baQax.mjs.map +0 -1
- package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +0 -1
- package/dist/planner-target-details-CIY6tLeo.d.mts.map +0 -1
- package/dist/postgres-contract-serializer-k3TAcPMY.mjs.map +0 -1
- package/dist/postgres-migration-B5jKrXv3.mjs.map +0 -1
- package/dist/postgres-migration-Y4YBJqkS.d.mts.map +0 -1
- package/dist/postgres-schema-COGZ1ark.mjs.map +0 -1
- package/dist/render-typescript-KMgosran.mjs.map +0 -1
- package/dist/types.d.mts.map +0 -1
- package/src/core/postgres-enum-type-schema.ts +0 -17
|
@@ -38,10 +38,22 @@ import { FunctionColumnDefault, LiteralColumnDefault } from '@prisma-next/sql-re
|
|
|
38
38
|
import { type ImportRequirement, jsonToTsSource, TsExpression } from '@prisma-next/ts-render';
|
|
39
39
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
40
40
|
import { ifDefined } from '@prisma-next/utils/defined';
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
columnExistsAst,
|
|
43
|
+
nativeEnumTypeExistsAst,
|
|
44
|
+
nativeEnumValueExistsAst,
|
|
45
|
+
tableExistsAst,
|
|
46
|
+
} from '../../contract-free/checks';
|
|
42
47
|
import * as contractFreeDdl from '../../contract-free/ddl';
|
|
43
|
-
import {
|
|
48
|
+
import type { PostgresRlsPolicy } from '../postgres-rls-policy';
|
|
49
|
+
import {
|
|
50
|
+
escapeLiteral,
|
|
51
|
+
quoteIdentifier,
|
|
52
|
+
quoteQualifiedName,
|
|
53
|
+
validateEnumValueLength,
|
|
54
|
+
} from '../sql-utils';
|
|
44
55
|
import type { PostgresColumnDefault } from '../types';
|
|
56
|
+
import { boundSchema } from './bound-schema';
|
|
45
57
|
import {
|
|
46
58
|
addNotNullColumnDirect,
|
|
47
59
|
alterColumnType,
|
|
@@ -61,6 +73,14 @@ import {
|
|
|
61
73
|
} from './operations/constraints';
|
|
62
74
|
import { createExtension } from './operations/dependencies';
|
|
63
75
|
import { createIndex, dropIndex } from './operations/indexes';
|
|
76
|
+
import { createNativeEnumType, dropNativeEnumType } from './operations/native-enum-types';
|
|
77
|
+
import {
|
|
78
|
+
createRlsPolicy,
|
|
79
|
+
disableRowLevelSecurity,
|
|
80
|
+
dropRlsPolicy,
|
|
81
|
+
enableRowLevelSecurity,
|
|
82
|
+
renameRlsPolicy,
|
|
83
|
+
} from './operations/rls';
|
|
64
84
|
import type { ForeignKeySpec } from './operations/shared';
|
|
65
85
|
import { step, targetDetails } from './operations/shared';
|
|
66
86
|
import { dropTable } from './operations/tables';
|
|
@@ -83,10 +103,6 @@ type Op = SqlMigrationPlanOperation<PostgresPlanTargetDetails>;
|
|
|
83
103
|
// transitive package on disk.
|
|
84
104
|
const POSTGRES_MIGRATION_FACADE = '@prisma-next/postgres/migration';
|
|
85
105
|
|
|
86
|
-
function boundSchema(schemaName: string): string | undefined {
|
|
87
|
-
return schemaName === UNBOUND_NAMESPACE_ID ? undefined : schemaName;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
106
|
abstract class PostgresOpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {
|
|
91
107
|
abstract readonly factoryName: string;
|
|
92
108
|
abstract readonly operationClass: MigrationOperationClass;
|
|
@@ -169,6 +185,8 @@ function renderDdlConstraintAsTsCall(constraint: DdlTableConstraint): string {
|
|
|
169
185
|
const nameOpt = constraint.name ? `, { name: ${jsonToTsSource(constraint.name)} }` : '';
|
|
170
186
|
return `unique(${jsonToTsSource(constraint.columns)}${nameOpt})`;
|
|
171
187
|
}
|
|
188
|
+
case 'check-expression':
|
|
189
|
+
return `checkExpression(${jsonToTsSource(constraint.name)}, ${jsonToTsSource(constraint.expression)})`;
|
|
172
190
|
}
|
|
173
191
|
}
|
|
174
192
|
|
|
@@ -183,6 +201,7 @@ function constraintImportSymbols(constraints: readonly DdlTableConstraint[] | un
|
|
|
183
201
|
if (c.kind === 'primary-key') symbols.add('primaryKey');
|
|
184
202
|
else if (c.kind === 'foreign-key') symbols.add('foreignKey');
|
|
185
203
|
else if (c.kind === 'unique') symbols.add('unique');
|
|
204
|
+
else if (c.kind === 'check-expression') symbols.add('checkExpression');
|
|
186
205
|
}
|
|
187
206
|
return [...symbols];
|
|
188
207
|
}
|
|
@@ -684,10 +703,8 @@ export class DropDefaultCall extends PostgresOpFactoryCallNode {
|
|
|
684
703
|
|
|
685
704
|
/**
|
|
686
705
|
* Planner-internal call for adding a NOT NULL column (no contract default) to
|
|
687
|
-
* a table that must be empty at migration time. Carries the
|
|
688
|
-
*
|
|
689
|
-
* DDL) plus the parameters needed to lower the typed pre/postchecks at render
|
|
690
|
-
* time.
|
|
706
|
+
* a table that must be empty at migration time. Carries the typed `DdlColumn`
|
|
707
|
+
* and lowers it to an ADD COLUMN execute step via the adapter at `toOp` time.
|
|
691
708
|
*
|
|
692
709
|
* No authored `PostgresMigration` method: this call is only emitted by the
|
|
693
710
|
* planner, never hand-written by migration authors.
|
|
@@ -698,15 +715,15 @@ export class AddNotNullColumnDirectCall extends PostgresOpFactoryCallNode {
|
|
|
698
715
|
readonly schemaName: string;
|
|
699
716
|
readonly tableName: string;
|
|
700
717
|
readonly columnName: string;
|
|
701
|
-
readonly
|
|
718
|
+
readonly column: DdlColumn;
|
|
702
719
|
readonly label: string;
|
|
703
720
|
|
|
704
|
-
constructor(schemaName: string, tableName: string, columnName: string,
|
|
721
|
+
constructor(schemaName: string, tableName: string, columnName: string, column: DdlColumn) {
|
|
705
722
|
super();
|
|
706
723
|
this.schemaName = schemaName;
|
|
707
724
|
this.tableName = tableName;
|
|
708
725
|
this.columnName = columnName;
|
|
709
|
-
this.
|
|
726
|
+
this.column = column;
|
|
710
727
|
this.label = `Add column ${columnName} to ${tableName}`;
|
|
711
728
|
this.freeze();
|
|
712
729
|
}
|
|
@@ -717,13 +734,7 @@ export class AddNotNullColumnDirectCall extends PostgresOpFactoryCallNode {
|
|
|
717
734
|
`AddNotNullColumnDirectCall.toOp: a lowerer is required on the Postgres planner path (column "${this.columnName}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
718
735
|
);
|
|
719
736
|
}
|
|
720
|
-
return addNotNullColumnDirect(
|
|
721
|
-
this.schemaName,
|
|
722
|
-
this.tableName,
|
|
723
|
-
this.columnName,
|
|
724
|
-
this.executeStepSql,
|
|
725
|
-
lowerer,
|
|
726
|
-
);
|
|
737
|
+
return addNotNullColumnDirect(this.schemaName, this.tableName, this.column, lowerer);
|
|
727
738
|
}
|
|
728
739
|
|
|
729
740
|
renderTypeScript(): string {
|
|
@@ -738,9 +749,9 @@ export class AddNotNullColumnDirectCall extends PostgresOpFactoryCallNode {
|
|
|
738
749
|
/**
|
|
739
750
|
* Planner-internal call for adding a NOT NULL column (no contract default)
|
|
740
751
|
* using a temporary default value for non-empty tables. Carries all parameters
|
|
741
|
-
* needed for `buildAddNotNullColumnWithTemporaryDefaultOperation`; the
|
|
742
|
-
* pre/postchecks are lowered
|
|
743
|
-
*
|
|
752
|
+
* needed for `buildAddNotNullColumnWithTemporaryDefaultOperation`; both the
|
|
753
|
+
* typed ADD COLUMN execute step and the pre/postchecks are lowered via the
|
|
754
|
+
* adapter at `toOp` time.
|
|
744
755
|
*
|
|
745
756
|
* No authored `PostgresMigration` method: this call is only emitted by the
|
|
746
757
|
* planner, never hand-written by migration authors.
|
|
@@ -1318,6 +1329,184 @@ export class CreateSchemaCall extends PostgresOpFactoryCallNode {
|
|
|
1318
1329
|
}
|
|
1319
1330
|
}
|
|
1320
1331
|
|
|
1332
|
+
// ============================================================================
|
|
1333
|
+
// Native enum types
|
|
1334
|
+
// ============================================================================
|
|
1335
|
+
|
|
1336
|
+
export class CreateNativeEnumTypeCall extends PostgresOpFactoryCallNode {
|
|
1337
|
+
readonly factoryName = 'createNativeEnumType' as const;
|
|
1338
|
+
readonly operationClass = 'additive' as const;
|
|
1339
|
+
readonly schemaName: string;
|
|
1340
|
+
readonly typeName: string;
|
|
1341
|
+
readonly members: readonly string[];
|
|
1342
|
+
readonly label: string;
|
|
1343
|
+
|
|
1344
|
+
constructor(schemaName: string, typeName: string, members: readonly string[]) {
|
|
1345
|
+
super();
|
|
1346
|
+
this.schemaName = schemaName;
|
|
1347
|
+
this.typeName = typeName;
|
|
1348
|
+
this.members = Object.freeze([...members]);
|
|
1349
|
+
this.label = `Create enum type "${typeName}"`;
|
|
1350
|
+
this.freeze();
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1354
|
+
if (lowerer === undefined) {
|
|
1355
|
+
throw new Error(
|
|
1356
|
+
`CreateNativeEnumTypeCall.toOp: a DDL lowerer is required on the Postgres planner path (type "${this.typeName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
return createNativeEnumType(this.schemaName, this.typeName, this.members, lowerer);
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
renderTypeScript(): string {
|
|
1363
|
+
const opts = [
|
|
1364
|
+
`schema: ${jsonToTsSource(this.schemaName)}`,
|
|
1365
|
+
`typeName: ${jsonToTsSource(this.typeName)}`,
|
|
1366
|
+
`members: ${jsonToTsSource(this.members)}`,
|
|
1367
|
+
];
|
|
1368
|
+
return `this.createNativeEnumType({ ${opts.join(', ')} })`;
|
|
1369
|
+
}
|
|
1370
|
+
|
|
1371
|
+
override importRequirements(): readonly ImportRequirement[] {
|
|
1372
|
+
return [];
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
export class DropNativeEnumTypeCall extends PostgresOpFactoryCallNode {
|
|
1377
|
+
readonly factoryName = 'dropNativeEnumType' as const;
|
|
1378
|
+
readonly operationClass = 'destructive' as const;
|
|
1379
|
+
readonly schemaName: string;
|
|
1380
|
+
readonly typeName: string;
|
|
1381
|
+
readonly label: string;
|
|
1382
|
+
|
|
1383
|
+
constructor(schemaName: string, typeName: string) {
|
|
1384
|
+
super();
|
|
1385
|
+
this.schemaName = schemaName;
|
|
1386
|
+
this.typeName = typeName;
|
|
1387
|
+
this.label = `Drop enum type "${typeName}"`;
|
|
1388
|
+
this.freeze();
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1392
|
+
if (lowerer === undefined) {
|
|
1393
|
+
throw new Error(
|
|
1394
|
+
`DropNativeEnumTypeCall.toOp: a DDL lowerer is required on the Postgres planner path (type "${this.typeName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
return dropNativeEnumType(this.schemaName, this.typeName, lowerer);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
renderTypeScript(): string {
|
|
1401
|
+
const opts = [
|
|
1402
|
+
`schema: ${jsonToTsSource(this.schemaName)}`,
|
|
1403
|
+
`typeName: ${jsonToTsSource(this.typeName)}`,
|
|
1404
|
+
];
|
|
1405
|
+
return `this.dropNativeEnumType({ ${opts.join(', ')} })`;
|
|
1406
|
+
}
|
|
1407
|
+
|
|
1408
|
+
override importRequirements(): readonly ImportRequirement[] {
|
|
1409
|
+
return [];
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
/** Schema-qualified, quoted enum type name — unqualified when `schemaName` is the unbound sentinel, matching `boundSchema`'s DDL-node convention. */
|
|
1414
|
+
function qualifiedNativeEnumTypeName(schemaName: string, typeName: string): string {
|
|
1415
|
+
const bound = boundSchema(schemaName);
|
|
1416
|
+
return quoteQualifiedName(bound === undefined ? typeName : `${bound}.${typeName}`);
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
const ADD_VALUE_TRANSACTION_CAVEAT =
|
|
1420
|
+
'A newly added enum value cannot be used until the transaction that adds it commits, so a ' +
|
|
1421
|
+
'migration that both appends a value and uses it in the same step will fail at apply.';
|
|
1422
|
+
|
|
1423
|
+
/**
|
|
1424
|
+
* `ALTER TYPE <qualified> ADD VALUE '<value>'` for a suffix-appended member on
|
|
1425
|
+
* a managed native enum. Built directly as SQL text (qualified via
|
|
1426
|
+
* `quoteQualifiedName`, the value escaped via `escapeLiteral`) rather than a
|
|
1427
|
+
* typed DDL node — mirrors how `enableRowLevelSecurity` renders its execute
|
|
1428
|
+
* step, since no DDL-AST node exists for this statement. Prechecks/postchecks
|
|
1429
|
+
* are still typed catalog queries lowered through the control adapter.
|
|
1430
|
+
* `validateEnumValueLength` runs at construction, so an over-length value
|
|
1431
|
+
* fails before planning produces a call.
|
|
1432
|
+
*/
|
|
1433
|
+
export class AddNativeEnumValueCall extends PostgresOpFactoryCallNode {
|
|
1434
|
+
readonly factoryName = 'addNativeEnumValue' as const;
|
|
1435
|
+
readonly operationClass = 'additive' as const;
|
|
1436
|
+
readonly schemaName: string;
|
|
1437
|
+
readonly typeName: string;
|
|
1438
|
+
readonly value: string;
|
|
1439
|
+
readonly label: string;
|
|
1440
|
+
readonly summary: string;
|
|
1441
|
+
|
|
1442
|
+
constructor(schemaName: string, typeName: string, value: string) {
|
|
1443
|
+
super();
|
|
1444
|
+
validateEnumValueLength(value, typeName);
|
|
1445
|
+
this.schemaName = schemaName;
|
|
1446
|
+
this.typeName = typeName;
|
|
1447
|
+
this.value = value;
|
|
1448
|
+
this.label = `Add value "${value}" to enum type "${typeName}"`;
|
|
1449
|
+
this.summary = `Adds value "${value}" to enum type "${typeName}". ${ADD_VALUE_TRANSACTION_CAVEAT}`;
|
|
1450
|
+
this.freeze();
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1454
|
+
if (lowerer === undefined) {
|
|
1455
|
+
throw new Error(
|
|
1456
|
+
`AddNativeEnumValueCall.toOp: a lowerer is required on the Postgres planner path (type "${this.typeName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
const { schemaName, typeName, value } = this;
|
|
1460
|
+
const typeChecks = nativeEnumTypeExistsAst(schemaName, typeName);
|
|
1461
|
+
const valueChecks = nativeEnumValueExistsAst({ schema: schemaName, typeName, value });
|
|
1462
|
+
const typePresent = await lowerer.lowerToExecuteRequest(typeChecks.typePresent());
|
|
1463
|
+
const valueAbsent = await lowerer.lowerToExecuteRequest(valueChecks.valueAbsent());
|
|
1464
|
+
const valuePresent = await lowerer.lowerToExecuteRequest(valueChecks.valuePresent());
|
|
1465
|
+
const qualifiedType = qualifiedNativeEnumTypeName(schemaName, typeName);
|
|
1466
|
+
return {
|
|
1467
|
+
id: `addNativeEnumValue.${typeName}.${value}`,
|
|
1468
|
+
label: this.label,
|
|
1469
|
+
summary: this.summary,
|
|
1470
|
+
operationClass: 'additive',
|
|
1471
|
+
target: targetDetails('type', typeName, schemaName),
|
|
1472
|
+
precheck: [
|
|
1473
|
+
step(`ensure enum type "${typeName}" exists`, typePresent.sql, typePresent.params),
|
|
1474
|
+
step(
|
|
1475
|
+
`ensure value "${value}" is absent from enum type "${typeName}"`,
|
|
1476
|
+
valueAbsent.sql,
|
|
1477
|
+
valueAbsent.params,
|
|
1478
|
+
),
|
|
1479
|
+
],
|
|
1480
|
+
execute: [
|
|
1481
|
+
step(
|
|
1482
|
+
`add value "${value}" to enum type "${typeName}"`,
|
|
1483
|
+
`ALTER TYPE ${qualifiedType} ADD VALUE '${escapeLiteral(value)}'`,
|
|
1484
|
+
),
|
|
1485
|
+
],
|
|
1486
|
+
postcheck: [
|
|
1487
|
+
step(
|
|
1488
|
+
`verify value "${value}" exists on enum type "${typeName}"`,
|
|
1489
|
+
valuePresent.sql,
|
|
1490
|
+
valuePresent.params,
|
|
1491
|
+
),
|
|
1492
|
+
],
|
|
1493
|
+
};
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
renderTypeScript(): string {
|
|
1497
|
+
const opts = [
|
|
1498
|
+
`schema: ${jsonToTsSource(this.schemaName)}`,
|
|
1499
|
+
`typeName: ${jsonToTsSource(this.typeName)}`,
|
|
1500
|
+
`value: ${jsonToTsSource(this.value)}`,
|
|
1501
|
+
];
|
|
1502
|
+
return `this.addNativeEnumValue({ ${opts.join(', ')} })`;
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
override importRequirements(): readonly ImportRequirement[] {
|
|
1506
|
+
return [];
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1321
1510
|
// ============================================================================
|
|
1322
1511
|
// Data transform
|
|
1323
1512
|
// ============================================================================
|
|
@@ -1376,6 +1565,169 @@ export class DataTransformCall extends PostgresOpFactoryCallNode {
|
|
|
1376
1565
|
}
|
|
1377
1566
|
}
|
|
1378
1567
|
|
|
1568
|
+
export class CreatePostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
|
|
1569
|
+
readonly factoryName = 'createRlsPolicy' as const;
|
|
1570
|
+
readonly operationClass = 'additive' as const;
|
|
1571
|
+
readonly schemaName: string;
|
|
1572
|
+
readonly tableName: string;
|
|
1573
|
+
readonly policy: PostgresRlsPolicy;
|
|
1574
|
+
readonly label: string;
|
|
1575
|
+
|
|
1576
|
+
constructor(schemaName: string, tableName: string, policy: PostgresRlsPolicy) {
|
|
1577
|
+
super();
|
|
1578
|
+
this.schemaName = schemaName;
|
|
1579
|
+
this.tableName = tableName;
|
|
1580
|
+
this.policy = policy;
|
|
1581
|
+
this.label = `Create RLS policy "${policy.name}" on "${tableName}"`;
|
|
1582
|
+
this.freeze();
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1586
|
+
if (lowerer === undefined) {
|
|
1587
|
+
throw new Error(
|
|
1588
|
+
`CreatePostgresRlsPolicyCall.toOp: a lowerer is required on the Postgres planner path (policy "${this.policy.name}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1589
|
+
);
|
|
1590
|
+
}
|
|
1591
|
+
return createRlsPolicy(this.schemaName, this.tableName, this.policy, lowerer);
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
renderTypeScript(): string {
|
|
1595
|
+
return `createRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.policy)})`;
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
export class DropPostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
|
|
1600
|
+
readonly factoryName = 'dropRlsPolicy' as const;
|
|
1601
|
+
readonly operationClass = 'destructive' as const;
|
|
1602
|
+
readonly schemaName: string;
|
|
1603
|
+
readonly tableName: string;
|
|
1604
|
+
readonly policyName: string;
|
|
1605
|
+
readonly label: string;
|
|
1606
|
+
|
|
1607
|
+
constructor(schemaName: string, tableName: string, policyName: string) {
|
|
1608
|
+
super();
|
|
1609
|
+
this.schemaName = schemaName;
|
|
1610
|
+
this.tableName = tableName;
|
|
1611
|
+
this.policyName = policyName;
|
|
1612
|
+
this.label = `Drop RLS policy "${policyName}" on "${tableName}"`;
|
|
1613
|
+
this.freeze();
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1617
|
+
if (lowerer === undefined) {
|
|
1618
|
+
throw new Error(
|
|
1619
|
+
`DropPostgresRlsPolicyCall.toOp: a lowerer is required on the Postgres planner path (policy "${this.policyName}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1620
|
+
);
|
|
1621
|
+
}
|
|
1622
|
+
return dropRlsPolicy(this.schemaName, this.tableName, this.policyName, lowerer);
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
renderTypeScript(): string {
|
|
1626
|
+
return `dropRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.policyName)})`;
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
export class EnableRowLevelSecurityCall extends PostgresOpFactoryCallNode {
|
|
1631
|
+
readonly factoryName = 'enableRowLevelSecurity' as const;
|
|
1632
|
+
readonly operationClass = 'additive' as const;
|
|
1633
|
+
readonly schemaName: string;
|
|
1634
|
+
readonly tableName: string;
|
|
1635
|
+
readonly label: string;
|
|
1636
|
+
|
|
1637
|
+
constructor(schemaName: string, tableName: string) {
|
|
1638
|
+
super();
|
|
1639
|
+
this.schemaName = schemaName;
|
|
1640
|
+
this.tableName = tableName;
|
|
1641
|
+
this.label = `Enable row-level security on "${tableName}"`;
|
|
1642
|
+
this.freeze();
|
|
1643
|
+
}
|
|
1644
|
+
|
|
1645
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1646
|
+
if (lowerer === undefined) {
|
|
1647
|
+
throw new Error(
|
|
1648
|
+
`EnableRowLevelSecurityCall.toOp: a lowerer is required on the Postgres planner path (table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1649
|
+
);
|
|
1650
|
+
}
|
|
1651
|
+
return enableRowLevelSecurity(this.schemaName, this.tableName, lowerer);
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
renderTypeScript(): string {
|
|
1655
|
+
return `enableRowLevelSecurity(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)})`;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
export class DisableRowLevelSecurityCall extends PostgresOpFactoryCallNode {
|
|
1660
|
+
readonly factoryName = 'disableRowLevelSecurity' as const;
|
|
1661
|
+
readonly operationClass = 'destructive' as const;
|
|
1662
|
+
readonly schemaName: string;
|
|
1663
|
+
readonly tableName: string;
|
|
1664
|
+
readonly label: string;
|
|
1665
|
+
|
|
1666
|
+
constructor(schemaName: string, tableName: string) {
|
|
1667
|
+
super();
|
|
1668
|
+
this.schemaName = schemaName;
|
|
1669
|
+
this.tableName = tableName;
|
|
1670
|
+
this.label = `Disable row-level security on "${tableName}"`;
|
|
1671
|
+
this.freeze();
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1675
|
+
if (lowerer === undefined) {
|
|
1676
|
+
throw new Error(
|
|
1677
|
+
`DisableRowLevelSecurityCall.toOp: a lowerer is required on the Postgres planner path (table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1678
|
+
);
|
|
1679
|
+
}
|
|
1680
|
+
return disableRowLevelSecurity(this.schemaName, this.tableName, lowerer);
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
renderTypeScript(): string {
|
|
1684
|
+
return `disableRowLevelSecurity(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)})`;
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
export class RenamePostgresRlsPolicyCall extends PostgresOpFactoryCallNode {
|
|
1689
|
+
readonly factoryName = 'renameRlsPolicy' as const;
|
|
1690
|
+
// `widening` is chosen so the rename plans under every allowance set except
|
|
1691
|
+
// additive-only init — a rename is neither additive-creation nor
|
|
1692
|
+
// destructive, and the class vocabulary has no neutral middle class. It is
|
|
1693
|
+
// NOT that a rename widens anything; this is the accepted typology tradeoff.
|
|
1694
|
+
readonly operationClass = 'widening' as const;
|
|
1695
|
+
readonly schemaName: string;
|
|
1696
|
+
readonly tableName: string;
|
|
1697
|
+
readonly oldPolicyName: string;
|
|
1698
|
+
readonly newPolicyName: string;
|
|
1699
|
+
readonly label: string;
|
|
1700
|
+
|
|
1701
|
+
constructor(schemaName: string, tableName: string, oldPolicyName: string, newPolicyName: string) {
|
|
1702
|
+
super();
|
|
1703
|
+
this.schemaName = schemaName;
|
|
1704
|
+
this.tableName = tableName;
|
|
1705
|
+
this.oldPolicyName = oldPolicyName;
|
|
1706
|
+
this.newPolicyName = newPolicyName;
|
|
1707
|
+
this.label = `Rename RLS policy "${oldPolicyName}" to "${newPolicyName}" on "${tableName}"`;
|
|
1708
|
+
this.freeze();
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
async toOp(lowerer?: ExecuteRequestLowerer): Promise<Op> {
|
|
1712
|
+
if (lowerer === undefined) {
|
|
1713
|
+
throw new Error(
|
|
1714
|
+
`RenamePostgresRlsPolicyCall.toOp: a lowerer is required on the Postgres planner path (policy "${this.oldPolicyName}" on table "${this.tableName}"). Pass the control adapter to createPostgresMigrationPlanner.`,
|
|
1715
|
+
);
|
|
1716
|
+
}
|
|
1717
|
+
return renameRlsPolicy(
|
|
1718
|
+
this.schemaName,
|
|
1719
|
+
this.tableName,
|
|
1720
|
+
this.oldPolicyName,
|
|
1721
|
+
this.newPolicyName,
|
|
1722
|
+
lowerer,
|
|
1723
|
+
);
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
renderTypeScript(): string {
|
|
1727
|
+
return `renameRlsPolicy(${jsonToTsSource(this.schemaName)}, ${jsonToTsSource(this.tableName)}, ${jsonToTsSource(this.oldPolicyName)}, ${jsonToTsSource(this.newPolicyName)})`;
|
|
1728
|
+
}
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1379
1731
|
export type PostgresOpFactoryCall =
|
|
1380
1732
|
| CreateTableCall
|
|
1381
1733
|
| DropTableCall
|
|
@@ -1399,4 +1751,12 @@ export type PostgresOpFactoryCall =
|
|
|
1399
1751
|
| RawSqlCall
|
|
1400
1752
|
| CreateExtensionCall
|
|
1401
1753
|
| CreateSchemaCall
|
|
1754
|
+
| CreateNativeEnumTypeCall
|
|
1755
|
+
| DropNativeEnumTypeCall
|
|
1756
|
+
| AddNativeEnumValueCall
|
|
1757
|
+
| CreatePostgresRlsPolicyCall
|
|
1758
|
+
| DropPostgresRlsPolicyCall
|
|
1759
|
+
| EnableRowLevelSecurityCall
|
|
1760
|
+
| DisableRowLevelSecurityCall
|
|
1761
|
+
| RenamePostgresRlsPolicyCall
|
|
1402
1762
|
| DataTransformCall;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';
|
|
2
|
+
import type { DdlColumn } from '@prisma-next/sql-relational-core/ast';
|
|
3
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
2
4
|
import {
|
|
3
5
|
columnDefaultAst,
|
|
4
6
|
columnExistsAst,
|
|
@@ -7,7 +9,9 @@ import {
|
|
|
7
9
|
noNullValuesAst,
|
|
8
10
|
tableIsEmptyAst,
|
|
9
11
|
} from '../../../contract-free/checks';
|
|
12
|
+
import * as contractFreeDdl from '../../../contract-free/ddl';
|
|
10
13
|
import { quoteIdentifier } from '../../sql-utils';
|
|
14
|
+
import { boundSchema } from '../bound-schema';
|
|
11
15
|
import { qualifyTableName } from '../planner-sql-checks';
|
|
12
16
|
import { type Op, step, targetDetails } from './shared';
|
|
13
17
|
|
|
@@ -242,12 +246,18 @@ export async function dropDefault(
|
|
|
242
246
|
columnName: string,
|
|
243
247
|
lowerer: ExecuteRequestLowerer,
|
|
244
248
|
): Promise<Op> {
|
|
245
|
-
const qualified = qualifyTableName(schemaName, tableName);
|
|
246
249
|
const { present } = await columnExistsSteps(lowerer, {
|
|
247
250
|
schema: schemaName,
|
|
248
251
|
table: tableName,
|
|
249
252
|
column: columnName,
|
|
250
253
|
});
|
|
254
|
+
const dropDefaultExec = await lowerer.lowerToExecuteRequest(
|
|
255
|
+
contractFreeDdl.alterTable({
|
|
256
|
+
...ifDefined('schema', boundSchema(schemaName)),
|
|
257
|
+
table: tableName,
|
|
258
|
+
actions: [contractFreeDdl.dropDefaultAction(columnName)],
|
|
259
|
+
}),
|
|
260
|
+
);
|
|
251
261
|
const noDefault = await lowerer.lowerToExecuteRequest(
|
|
252
262
|
columnDefaultAst({ schema: schemaName, table: tableName, column: columnName }).defaultAbsent(),
|
|
253
263
|
);
|
|
@@ -257,12 +267,7 @@ export async function dropDefault(
|
|
|
257
267
|
operationClass: 'destructive',
|
|
258
268
|
target: targetDetails('column', columnName, schemaName, tableName),
|
|
259
269
|
precheck: [step(`ensure column "${columnName}" exists`, present.sql, present.params)],
|
|
260
|
-
execute: [
|
|
261
|
-
step(
|
|
262
|
-
`drop default on "${columnName}"`,
|
|
263
|
-
`ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} DROP DEFAULT`,
|
|
264
|
-
),
|
|
265
|
-
],
|
|
270
|
+
execute: [step(`drop default on "${columnName}"`, dropDefaultExec.sql)],
|
|
266
271
|
postcheck: [
|
|
267
272
|
step(`verify column "${columnName}" has no default`, noDefault.sql, noDefault.params),
|
|
268
273
|
],
|
|
@@ -272,16 +277,23 @@ export async function dropDefault(
|
|
|
272
277
|
/**
|
|
273
278
|
* Builds the op for adding a NOT NULL column (no contract default) to a
|
|
274
279
|
* non-empty table. Prechecks assert the column is absent and the table is
|
|
275
|
-
* empty; the execute step
|
|
276
|
-
*
|
|
280
|
+
* empty; the execute step lowers the typed `AddColumn` DDL node through the
|
|
281
|
+
* adapter; postchecks assert the column exists and is NOT NULL.
|
|
277
282
|
*/
|
|
278
283
|
export async function addNotNullColumnDirect(
|
|
279
284
|
schemaName: string,
|
|
280
285
|
tableName: string,
|
|
281
|
-
|
|
282
|
-
executeStepSql: string,
|
|
286
|
+
column: DdlColumn,
|
|
283
287
|
lowerer: ExecuteRequestLowerer,
|
|
284
288
|
): Promise<Op> {
|
|
289
|
+
const columnName = column.name;
|
|
290
|
+
const addColumn = await lowerer.lowerToExecuteRequest(
|
|
291
|
+
contractFreeDdl.alterTable({
|
|
292
|
+
...ifDefined('schema', boundSchema(schemaName)),
|
|
293
|
+
table: tableName,
|
|
294
|
+
actions: [contractFreeDdl.addColumnAction(column)],
|
|
295
|
+
}),
|
|
296
|
+
);
|
|
285
297
|
const absent = await lowerer.lowerToExecuteRequest(
|
|
286
298
|
columnExistsAst({ schema: schemaName, table: tableName, column: columnName }).columnAbsent(),
|
|
287
299
|
);
|
|
@@ -311,7 +323,7 @@ export async function addNotNullColumnDirect(
|
|
|
311
323
|
tableEmpty.params,
|
|
312
324
|
),
|
|
313
325
|
],
|
|
314
|
-
execute: [step(`add column "${columnName}"`,
|
|
326
|
+
execute: [step(`add column "${columnName}"`, addColumn.sql)],
|
|
315
327
|
postcheck: [
|
|
316
328
|
step(`verify column "${columnName}" exists`, present.sql, present.params),
|
|
317
329
|
step(`verify column "${columnName}" is NOT NULL`, notNullable.sql, notNullable.params),
|
|
@@ -196,7 +196,7 @@ export async function dropCheckConstraint(
|
|
|
196
196
|
* `kind` feeds the operation's `target.details.objectType`. Descriptor-flow
|
|
197
197
|
* does not carry kind information in its drop-constraint descriptor, so the
|
|
198
198
|
* default is `'unique'`. The reconciliation planner passes the correct kind
|
|
199
|
-
* (`'foreignKey'`, `'primaryKey'`, or `'unique'`) based on the
|
|
199
|
+
* (`'foreignKey'`, `'primaryKey'`, or `'unique'`) based on the diff issue
|
|
200
200
|
* that produced the drop.
|
|
201
201
|
*/
|
|
202
202
|
export async function dropConstraint(
|
|
@@ -113,6 +113,12 @@ export async function dataTransform<TContract extends Contract<SqlStorage>>(
|
|
|
113
113
|
runClosures.map((closure) => invokeAndLower(closure, contract, adapter, name)),
|
|
114
114
|
);
|
|
115
115
|
|
|
116
|
+
// Raw remnant: the factory lowered the user's `check` plan above before
|
|
117
|
+
// we get a chance to wrap it, so the EXISTS lifting only has text by the
|
|
118
|
+
// time it runs. The fix is to rewrite the factory to defer lowering until
|
|
119
|
+
// after wrapping — so `cfExpr.exists(checkPlan.ast)` can produce the
|
|
120
|
+
// EXISTS query, then lower once at the boundary — not to grow new AST
|
|
121
|
+
// substrate. Out of scope for the slice that introduced this comment.
|
|
116
122
|
const precheck: readonly SqlMigrationPlanOperationStep[] = checkPlan
|
|
117
123
|
? [
|
|
118
124
|
{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';
|
|
2
2
|
import { extensionExistsAst } from '../../../contract-free/checks';
|
|
3
|
+
import { DEFAULT_NAMESPACE_ID } from '../../namespace-ids';
|
|
3
4
|
import { quoteIdentifier } from '../../sql-utils';
|
|
4
5
|
import { type Op, step } from './shared';
|
|
5
6
|
|
|
@@ -55,7 +56,7 @@ export async function installExtension(
|
|
|
55
56
|
invariantId,
|
|
56
57
|
target: {
|
|
57
58
|
id: 'postgres',
|
|
58
|
-
details: { schema:
|
|
59
|
+
details: { schema: DEFAULT_NAMESPACE_ID, objectType: 'dependency', name: extensionName },
|
|
59
60
|
},
|
|
60
61
|
precheck: [
|
|
61
62
|
step(`verify extension "${extensionName}" is not already enabled`, absent.sql, absent.params),
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';
|
|
2
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
3
|
+
import { createType, dropType } from '../../../contract-free/ddl';
|
|
4
|
+
import { validateEnumValueLength } from '../../sql-utils';
|
|
5
|
+
import { boundSchema } from '../bound-schema';
|
|
6
|
+
import { type Op, step, targetDetails } from './shared';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `CREATE TYPE <qualified> AS ENUM (…)` for a managed native enum, built as a
|
|
10
|
+
* typed DDL node and lowered by the control adapter (the type name is quoted,
|
|
11
|
+
* member values render as escaped string literals in declaration order —
|
|
12
|
+
* Postgres enum sort order is semantic). `boundSchema` maps the unbound sentinel
|
|
13
|
+
* to an absent schema so the type name renders unqualified and the connection's
|
|
14
|
+
* `search_path` resolves the schema at runtime.
|
|
15
|
+
*/
|
|
16
|
+
export async function createNativeEnumType(
|
|
17
|
+
schemaName: string,
|
|
18
|
+
typeName: string,
|
|
19
|
+
members: readonly string[],
|
|
20
|
+
lowerer: ExecuteRequestLowerer,
|
|
21
|
+
): Promise<Op> {
|
|
22
|
+
for (const member of members) {
|
|
23
|
+
validateEnumValueLength(member, typeName);
|
|
24
|
+
}
|
|
25
|
+
const ddlNode = createType({
|
|
26
|
+
...ifDefined('schema', boundSchema(schemaName)),
|
|
27
|
+
name: typeName,
|
|
28
|
+
values: members,
|
|
29
|
+
});
|
|
30
|
+
const statement = await lowerer.lowerToExecuteRequest(ddlNode);
|
|
31
|
+
return {
|
|
32
|
+
id: `createNativeEnumType.${typeName}`,
|
|
33
|
+
label: `Create enum type "${typeName}"`,
|
|
34
|
+
operationClass: 'additive',
|
|
35
|
+
target: targetDetails('type', typeName, schemaName),
|
|
36
|
+
precheck: [],
|
|
37
|
+
execute: [step(`create enum type "${typeName}"`, statement.sql, statement.params)],
|
|
38
|
+
postcheck: [],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `DROP TYPE <qualified>` for an unclaimed managed native enum, via typed DDL. */
|
|
43
|
+
export async function dropNativeEnumType(
|
|
44
|
+
schemaName: string,
|
|
45
|
+
typeName: string,
|
|
46
|
+
lowerer: ExecuteRequestLowerer,
|
|
47
|
+
): Promise<Op> {
|
|
48
|
+
const ddlNode = dropType({
|
|
49
|
+
...ifDefined('schema', boundSchema(schemaName)),
|
|
50
|
+
name: typeName,
|
|
51
|
+
});
|
|
52
|
+
const statement = await lowerer.lowerToExecuteRequest(ddlNode);
|
|
53
|
+
return {
|
|
54
|
+
id: `dropNativeEnumType.${typeName}`,
|
|
55
|
+
label: `Drop enum type "${typeName}"`,
|
|
56
|
+
operationClass: 'destructive',
|
|
57
|
+
target: targetDetails('type', typeName, schemaName),
|
|
58
|
+
precheck: [],
|
|
59
|
+
execute: [step(`drop enum type "${typeName}"`, statement.sql, statement.params)],
|
|
60
|
+
postcheck: [],
|
|
61
|
+
};
|
|
62
|
+
}
|