@prisma-next/target-postgres 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{codec-ids-CTikp1if.mjs → codec-ids-BvytN2P8.mjs} +3 -3
- package/dist/codec-ids-BvytN2P8.mjs.map +1 -0
- package/dist/{codec-ids-B1vOchLE.d.mts → codec-ids-CnXu9Qy3.d.mts} +3 -3
- package/dist/codec-ids-CnXu9Qy3.d.mts.map +1 -0
- package/dist/codec-ids.d.mts +2 -2
- package/dist/codec-ids.mjs +2 -2
- package/dist/{codec-types-CnFiNML4.d.mts → codec-types-DHCkwPKE.d.mts} +3 -3
- package/dist/{codec-types-CnFiNML4.d.mts.map → codec-types-DHCkwPKE.d.mts.map} +1 -1
- package/dist/codec-types.d.mts +1 -1
- package/dist/{codecs-CBpEv4s5.d.mts → codecs--0A5_4Bq.d.mts} +26 -23
- package/dist/codecs--0A5_4Bq.d.mts.map +1 -0
- package/dist/codecs.d.mts +2 -2
- package/dist/codecs.mjs +28 -35
- package/dist/codecs.mjs.map +1 -1
- package/dist/contract-free.d.mts +163 -15
- package/dist/contract-free.d.mts.map +1 -1
- package/dist/contract-free.mjs +4 -17
- package/dist/contract-free.mjs.map +1 -1
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +21 -27
- package/dist/control.mjs.map +1 -1
- package/dist/{data-transform-D25tLeYU.mjs → data-transform-BOWpliq8.mjs} +9 -17
- package/dist/data-transform-BOWpliq8.mjs.map +1 -0
- package/dist/{data-transform-DGOqcLrf.d.mts → data-transform-DDgWdB5o.d.mts} +2 -2
- package/dist/data-transform-DDgWdB5o.d.mts.map +1 -0
- package/dist/data-transform.d.mts +1 -1
- package/dist/data-transform.mjs +1 -1
- package/dist/ddl-QDyOSeLc.mjs +251 -0
- package/dist/ddl-QDyOSeLc.mjs.map +1 -0
- package/dist/ddl.d.mts +2 -2
- package/dist/ddl.mjs +2 -2
- package/dist/descriptor-meta-CpGygXpI.mjs +140 -0
- package/dist/descriptor-meta-CpGygXpI.mjs.map +1 -0
- package/dist/{issue-planner-Br0pt1Ea.mjs → issue-planner-DL6g3CmE.mjs} +52 -366
- package/dist/issue-planner-DL6g3CmE.mjs.map +1 -0
- package/dist/issue-planner.d.mts +8 -11
- package/dist/issue-planner.d.mts.map +1 -1
- package/dist/issue-planner.mjs +1 -1
- package/dist/migration.d.mts +5 -92
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +4 -4
- package/dist/{nodes-DZk2JZG3.mjs → nodes-Bbhs2rwj.mjs} +31 -2
- package/dist/nodes-Bbhs2rwj.mjs.map +1 -0
- package/dist/{nodes-779hmCfL.d.mts → nodes-pLeLgdis.d.mts} +30 -3
- package/dist/nodes-pLeLgdis.d.mts.map +1 -0
- package/dist/{op-factory-call-D2aAUhmS.mjs → op-factory-call-D_p5vxwt.mjs} +601 -418
- package/dist/op-factory-call-D_p5vxwt.mjs.map +1 -0
- package/dist/{op-factory-call-DMA86_2D.d.mts → op-factory-call-DmQEc3XV.d.mts} +119 -72
- package/dist/op-factory-call-DmQEc3XV.d.mts.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 +36 -15
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +1 -1
- package/dist/{planner-CAYPJObw.mjs → planner-Bs_baQax.mjs} +25 -45
- package/dist/planner-Bs_baQax.mjs.map +1 -0
- package/dist/{planner-ddl-builders-Cw2n2llW.mjs → planner-ddl-builders-B2wOwLqI.mjs} +2 -2
- package/dist/planner-ddl-builders-B2wOwLqI.mjs.map +1 -0
- package/dist/planner-ddl-builders.d.mts +4 -4
- package/dist/planner-ddl-builders.d.mts.map +1 -1
- package/dist/planner-ddl-builders.mjs +1 -1
- package/dist/{planner-identity-values-BIpa5p2I.mjs → planner-identity-values-CJPha2Sz.mjs} +3 -9
- package/dist/planner-identity-values-CJPha2Sz.mjs.map +1 -0
- package/dist/planner-identity-values.d.mts +1 -1
- package/dist/planner-identity-values.d.mts.map +1 -1
- package/dist/planner-identity-values.mjs +1 -1
- package/dist/{planner-produced-postgres-migration-NSEhWL0L.mjs → planner-produced-postgres-migration-Cji5vxUf.mjs} +6 -4
- package/dist/planner-produced-postgres-migration-Cji5vxUf.mjs.map +1 -0
- package/dist/{planner-produced-postgres-migration-B4EDvLdz.d.mts → planner-produced-postgres-migration-QqHa2C2l.d.mts} +5 -6
- package/dist/planner-produced-postgres-migration-QqHa2C2l.d.mts.map +1 -0
- 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 +152 -0
- package/dist/planner-sql-checks-jqUUGyQR.mjs.map +1 -0
- package/dist/planner-sql-checks.d.mts +3 -49
- package/dist/planner-sql-checks.d.mts.map +1 -1
- package/dist/planner-sql-checks.mjs +2 -2
- package/dist/{planner-type-resolution-836DExFN.mjs → planner-type-resolution-Bt2f_q-F.mjs} +1 -6
- package/dist/planner-type-resolution-Bt2f_q-F.mjs.map +1 -0
- package/dist/planner.d.mts +4 -4
- package/dist/planner.d.mts.map +1 -1
- package/dist/planner.mjs +1 -1
- package/dist/{postgres-contract-serializer-DYTyXjPf.mjs → postgres-contract-serializer-k3TAcPMY.mjs} +30 -37
- package/dist/postgres-contract-serializer-k3TAcPMY.mjs.map +1 -0
- package/dist/postgres-migration-B5jKrXv3.mjs +145 -0
- package/dist/postgres-migration-B5jKrXv3.mjs.map +1 -0
- package/dist/postgres-migration-Y4YBJqkS.d.mts +181 -0
- package/dist/postgres-migration-Y4YBJqkS.d.mts.map +1 -0
- package/dist/{postgres-schema-BuxCxbvB.mjs → postgres-schema-COGZ1ark.mjs} +82 -23
- package/dist/postgres-schema-COGZ1ark.mjs.map +1 -0
- package/dist/{render-ops-BpjstrKQ.mjs → render-ops-BREh1kHe.mjs} +10 -5
- package/dist/render-ops-BREh1kHe.mjs.map +1 -0
- package/dist/render-ops.d.mts +2 -2
- package/dist/render-ops.d.mts.map +1 -1
- package/dist/render-ops.mjs +1 -1
- package/dist/runtime.d.mts +1 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/dist/table-source-BvFo7gVs.d.mts +15 -0
- package/dist/table-source-BvFo7gVs.d.mts.map +1 -0
- package/dist/types.d.mts +34 -19
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +2 -3
- package/package.json +17 -18
- package/src/contract-free/checks.ts +363 -0
- package/src/contract-free/ddl.ts +28 -1
- package/src/core/authoring.ts +43 -44
- package/src/core/codec-helpers.ts +0 -17
- package/src/core/codec-ids.ts +1 -1
- package/src/core/codec-type-map.ts +2 -2
- package/src/core/codecs.ts +43 -48
- package/src/core/ddl/nodes.ts +59 -1
- package/src/core/migrations/control-policy.ts +17 -47
- package/src/core/migrations/issue-planner.ts +34 -70
- package/src/core/migrations/op-factory-call.ts +486 -215
- package/src/core/migrations/operations/columns.ts +175 -140
- package/src/core/migrations/operations/constraints.ts +79 -108
- package/src/core/migrations/operations/data-transform.ts +15 -18
- package/src/core/migrations/operations/dependencies.ts +16 -14
- package/src/core/migrations/operations/indexes.ts +31 -28
- package/src/core/migrations/operations/shared.ts +2 -2
- package/src/core/migrations/operations/tables.ts +13 -14
- package/src/core/migrations/planner-ddl-builders.ts +3 -4
- package/src/core/migrations/planner-identity-values.ts +4 -28
- package/src/core/migrations/planner-produced-postgres-migration.ts +15 -7
- package/src/core/migrations/planner-recipes.ts +44 -39
- package/src/core/migrations/planner-sql-checks.ts +3 -178
- package/src/core/migrations/planner-strategies.ts +76 -449
- package/src/core/migrations/planner-type-resolution.ts +2 -20
- package/src/core/migrations/planner.ts +6 -6
- package/src/core/migrations/postgres-migration.ts +287 -7
- package/src/core/migrations/render-ops.ts +26 -13
- package/src/core/migrations/runner.ts +26 -20
- package/src/core/postgres-contract-serializer.ts +37 -54
- package/src/core/postgres-enum-type-schema.ts +17 -0
- package/src/core/postgres-schema.ts +86 -46
- package/src/exports/codecs.ts +2 -2
- package/src/exports/contract-free.ts +22 -1
- package/src/exports/control.ts +0 -22
- package/src/exports/ddl.ts +4 -0
- package/src/exports/migration.ts +1 -29
- package/src/exports/op-factory-call.ts +0 -4
- package/src/exports/planner-sql-checks.ts +0 -7
- package/src/exports/types.ts +0 -1
- package/dist/codec-ids-B1vOchLE.d.mts.map +0 -1
- package/dist/codec-ids-CTikp1if.mjs.map +0 -1
- package/dist/codecs-CBpEv4s5.d.mts.map +0 -1
- package/dist/data-transform-D25tLeYU.mjs.map +0 -1
- package/dist/data-transform-DGOqcLrf.d.mts.map +0 -1
- package/dist/ddl-77SyXgFt.mjs +0 -30
- package/dist/ddl-77SyXgFt.mjs.map +0 -1
- package/dist/descriptor-meta-DKmj-IMN.mjs +0 -14
- package/dist/descriptor-meta-DKmj-IMN.mjs.map +0 -1
- package/dist/descriptor-meta-runtime-My8_s4cs.mjs +0 -130
- package/dist/descriptor-meta-runtime-My8_s4cs.mjs.map +0 -1
- package/dist/enum-planning-BCyvlFHk.mjs +0 -0
- package/dist/enum-planning-BCyvlFHk.mjs.map +0 -1
- package/dist/enum-planning.d.mts +0 -86
- package/dist/enum-planning.d.mts.map +0 -1
- package/dist/enum-planning.mjs +0 -2
- package/dist/issue-planner-Br0pt1Ea.mjs.map +0 -1
- package/dist/nodes-779hmCfL.d.mts.map +0 -1
- package/dist/nodes-DZk2JZG3.mjs.map +0 -1
- package/dist/op-factory-call-D2aAUhmS.mjs.map +0 -1
- package/dist/op-factory-call-DMA86_2D.d.mts.map +0 -1
- package/dist/planner-CAYPJObw.mjs.map +0 -1
- package/dist/planner-ddl-builders-Cw2n2llW.mjs.map +0 -1
- package/dist/planner-identity-values-BIpa5p2I.mjs.map +0 -1
- package/dist/planner-produced-postgres-migration-B4EDvLdz.d.mts.map +0 -1
- package/dist/planner-produced-postgres-migration-NSEhWL0L.mjs.map +0 -1
- package/dist/planner-sql-checks-DAdhnI2c.mjs +0 -272
- package/dist/planner-sql-checks-DAdhnI2c.mjs.map +0 -1
- package/dist/planner-type-resolution-836DExFN.mjs.map +0 -1
- package/dist/postgres-contract-serializer-DYTyXjPf.mjs.map +0 -1
- package/dist/postgres-enum-type-BVn63a89.d.mts +0 -72
- package/dist/postgres-enum-type-BVn63a89.d.mts.map +0 -1
- package/dist/postgres-enum-type-DPKqCBem.mjs +0 -62
- package/dist/postgres-enum-type-DPKqCBem.mjs.map +0 -1
- package/dist/postgres-migration-COore9Mz.mjs +0 -71
- package/dist/postgres-migration-COore9Mz.mjs.map +0 -1
- package/dist/postgres-migration-DZ_gLUOW.d.mts +0 -72
- package/dist/postgres-migration-DZ_gLUOW.d.mts.map +0 -1
- package/dist/postgres-schema-BuxCxbvB.mjs.map +0 -1
- package/dist/render-ops-BpjstrKQ.mjs.map +0 -1
- package/dist/shared-DarONYBZ.d.mts +0 -43
- package/dist/shared-DarONYBZ.d.mts.map +0 -1
- package/src/core/migrations/enum-planning.ts +0 -213
- package/src/core/migrations/operations/enums.ts +0 -114
- package/src/core/postgres-enum-type.ts +0 -89
- package/src/exports/enum-planning.ts +0 -11
|
@@ -1,79 +1,53 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ExecuteRequestLowerer } from '@prisma-next/family-sql/control-adapter';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
columnDefaultAst,
|
|
4
|
+
columnExistsAst,
|
|
5
|
+
columnNullabilityAst,
|
|
6
|
+
columnTypeAst,
|
|
7
|
+
noNullValuesAst,
|
|
8
|
+
tableIsEmptyAst,
|
|
9
|
+
} from '../../../contract-free/checks';
|
|
10
|
+
import { quoteIdentifier } from '../../sql-utils';
|
|
11
|
+
import { qualifyTableName } from '../planner-sql-checks';
|
|
12
|
+
import { type Op, step, targetDetails } from './shared';
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
const qualified = qualifyTableName(schemaName, tableName);
|
|
13
|
-
const parts = [
|
|
14
|
-
`ALTER TABLE ${qualified}`,
|
|
15
|
-
`ADD COLUMN ${quoteIdentifier(column.name)} ${column.typeSql}`,
|
|
16
|
-
column.defaultSql,
|
|
17
|
-
column.nullable ? '' : 'NOT NULL',
|
|
18
|
-
].filter(Boolean);
|
|
19
|
-
const addSql = parts.join(' ');
|
|
14
|
+
type CheckStep = { sql: string; params?: readonly unknown[] };
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
columnExistsCheck({
|
|
30
|
-
schema: schemaName,
|
|
31
|
-
table: tableName,
|
|
32
|
-
column: column.name,
|
|
33
|
-
exists: false,
|
|
34
|
-
}),
|
|
35
|
-
),
|
|
36
|
-
],
|
|
37
|
-
execute: [step(`add column "${column.name}"`, addSql)],
|
|
38
|
-
postcheck: [
|
|
39
|
-
step(
|
|
40
|
-
`verify column "${column.name}" exists`,
|
|
41
|
-
columnExistsCheck({ schema: schemaName, table: tableName, column: column.name }),
|
|
42
|
-
),
|
|
43
|
-
],
|
|
44
|
-
};
|
|
16
|
+
async function columnExistsSteps(
|
|
17
|
+
lowerer: ExecuteRequestLowerer,
|
|
18
|
+
options: { schema: string; table: string; column: string },
|
|
19
|
+
): Promise<{ present: CheckStep; absent: CheckStep }> {
|
|
20
|
+
const checks = columnExistsAst(options);
|
|
21
|
+
const present = await lowerer.lowerToExecuteRequest(checks.columnPresent());
|
|
22
|
+
const absent = await lowerer.lowerToExecuteRequest(checks.columnAbsent());
|
|
23
|
+
return { present, absent };
|
|
45
24
|
}
|
|
46
25
|
|
|
47
|
-
export function dropColumn(
|
|
26
|
+
export async function dropColumn(
|
|
27
|
+
schemaName: string,
|
|
28
|
+
tableName: string,
|
|
29
|
+
columnName: string,
|
|
30
|
+
lowerer: ExecuteRequestLowerer,
|
|
31
|
+
): Promise<Op> {
|
|
48
32
|
const qualified = qualifyTableName(schemaName, tableName);
|
|
33
|
+
const { present, absent } = await columnExistsSteps(lowerer, {
|
|
34
|
+
schema: schemaName,
|
|
35
|
+
table: tableName,
|
|
36
|
+
column: columnName,
|
|
37
|
+
});
|
|
49
38
|
return {
|
|
50
39
|
id: `dropColumn.${tableName}.${columnName}`,
|
|
51
40
|
label: `Drop column "${columnName}" from "${tableName}"`,
|
|
52
41
|
operationClass: 'destructive',
|
|
53
42
|
target: targetDetails('column', columnName, schemaName, tableName),
|
|
54
|
-
precheck: [
|
|
55
|
-
step(
|
|
56
|
-
`ensure column "${columnName}" exists`,
|
|
57
|
-
columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),
|
|
58
|
-
),
|
|
59
|
-
],
|
|
43
|
+
precheck: [step(`ensure column "${columnName}" exists`, present.sql, present.params)],
|
|
60
44
|
execute: [
|
|
61
45
|
step(
|
|
62
46
|
`drop column "${columnName}"`,
|
|
63
47
|
`ALTER TABLE ${qualified} DROP COLUMN ${quoteIdentifier(columnName)}`,
|
|
64
48
|
),
|
|
65
49
|
],
|
|
66
|
-
postcheck: [
|
|
67
|
-
step(
|
|
68
|
-
`verify column "${columnName}" does not exist`,
|
|
69
|
-
columnExistsCheck({
|
|
70
|
-
schema: schemaName,
|
|
71
|
-
table: tableName,
|
|
72
|
-
column: columnName,
|
|
73
|
-
exists: false,
|
|
74
|
-
}),
|
|
75
|
-
),
|
|
76
|
-
],
|
|
50
|
+
postcheck: [step(`verify column "${columnName}" does not exist`, absent.sql, absent.params)],
|
|
77
51
|
};
|
|
78
52
|
}
|
|
79
53
|
|
|
@@ -85,7 +59,7 @@ export function dropColumn(schemaName: string, tableName: string, columnName: st
|
|
|
85
59
|
* string appearing in the human-readable label (typically `toType` when
|
|
86
60
|
* explicit, else the column's native type).
|
|
87
61
|
*/
|
|
88
|
-
export function alterColumnType(
|
|
62
|
+
export async function alterColumnType(
|
|
89
63
|
schemaName: string,
|
|
90
64
|
tableName: string,
|
|
91
65
|
columnName: string,
|
|
@@ -95,22 +69,31 @@ export function alterColumnType(
|
|
|
95
69
|
readonly rawTargetTypeForLabel: string;
|
|
96
70
|
readonly using?: string;
|
|
97
71
|
},
|
|
98
|
-
|
|
72
|
+
lowerer: ExecuteRequestLowerer,
|
|
73
|
+
): Promise<Op> {
|
|
99
74
|
const qualified = qualifyTableName(schemaName, tableName);
|
|
100
75
|
const usingClause = options.using
|
|
101
76
|
? ` USING ${options.using}`
|
|
102
77
|
: ` USING ${quoteIdentifier(columnName)}::${options.qualifiedTargetType}`;
|
|
78
|
+
const { present } = await columnExistsSteps(lowerer, {
|
|
79
|
+
schema: schemaName,
|
|
80
|
+
table: tableName,
|
|
81
|
+
column: columnName,
|
|
82
|
+
});
|
|
83
|
+
const typeCheck = await lowerer.lowerToExecuteRequest(
|
|
84
|
+
columnTypeAst({
|
|
85
|
+
schema: schemaName,
|
|
86
|
+
table: tableName,
|
|
87
|
+
column: columnName,
|
|
88
|
+
expectedType: options.formatTypeExpected,
|
|
89
|
+
}),
|
|
90
|
+
);
|
|
103
91
|
return {
|
|
104
92
|
id: `alterType.${tableName}.${columnName}`,
|
|
105
93
|
label: `Alter type of "${tableName}"."${columnName}" to ${options.rawTargetTypeForLabel}`,
|
|
106
94
|
operationClass: 'destructive',
|
|
107
95
|
target: targetDetails('column', columnName, schemaName, tableName),
|
|
108
|
-
precheck: [
|
|
109
|
-
step(
|
|
110
|
-
`ensure column "${columnName}" exists`,
|
|
111
|
-
columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),
|
|
112
|
-
),
|
|
113
|
-
],
|
|
96
|
+
precheck: [step(`ensure column "${columnName}" exists`, present.sql, present.params)],
|
|
114
97
|
execute: [
|
|
115
98
|
step(
|
|
116
99
|
`alter type of "${columnName}"`,
|
|
@@ -120,34 +103,45 @@ export function alterColumnType(
|
|
|
120
103
|
postcheck: [
|
|
121
104
|
step(
|
|
122
105
|
`verify column "${columnName}" has type "${options.formatTypeExpected}"`,
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
table: tableName,
|
|
126
|
-
column: columnName,
|
|
127
|
-
expectedType: options.formatTypeExpected,
|
|
128
|
-
}),
|
|
106
|
+
typeCheck.sql,
|
|
107
|
+
typeCheck.params,
|
|
129
108
|
),
|
|
130
109
|
],
|
|
131
110
|
meta: { warning: 'TABLE_REWRITE' },
|
|
132
111
|
};
|
|
133
112
|
}
|
|
134
113
|
|
|
135
|
-
export function setNotNull(
|
|
114
|
+
export async function setNotNull(
|
|
115
|
+
schemaName: string,
|
|
116
|
+
tableName: string,
|
|
117
|
+
columnName: string,
|
|
118
|
+
lowerer: ExecuteRequestLowerer,
|
|
119
|
+
): Promise<Op> {
|
|
136
120
|
const qualified = qualifyTableName(schemaName, tableName);
|
|
121
|
+
const { present } = await columnExistsSteps(lowerer, {
|
|
122
|
+
schema: schemaName,
|
|
123
|
+
table: tableName,
|
|
124
|
+
column: columnName,
|
|
125
|
+
});
|
|
126
|
+
const noNulls = await lowerer.lowerToExecuteRequest(
|
|
127
|
+
noNullValuesAst({ schema: schemaName, table: tableName, column: columnName }),
|
|
128
|
+
);
|
|
129
|
+
const notNullable = await lowerer.lowerToExecuteRequest(
|
|
130
|
+
columnNullabilityAst({
|
|
131
|
+
schema: schemaName,
|
|
132
|
+
table: tableName,
|
|
133
|
+
column: columnName,
|
|
134
|
+
nullable: false,
|
|
135
|
+
}),
|
|
136
|
+
);
|
|
137
137
|
return {
|
|
138
138
|
id: `alterNullability.setNotNull.${tableName}.${columnName}`,
|
|
139
139
|
label: `Set NOT NULL on "${tableName}"."${columnName}"`,
|
|
140
140
|
operationClass: 'destructive',
|
|
141
141
|
target: targetDetails('column', columnName, schemaName, tableName),
|
|
142
142
|
precheck: [
|
|
143
|
-
step(
|
|
144
|
-
|
|
145
|
-
columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),
|
|
146
|
-
),
|
|
147
|
-
step(
|
|
148
|
-
`ensure no NULL values in "${columnName}"`,
|
|
149
|
-
`SELECT NOT EXISTS (SELECT 1 FROM ${qualified} WHERE ${quoteIdentifier(columnName)} IS NULL)`,
|
|
150
|
-
),
|
|
143
|
+
step(`ensure column "${columnName}" exists`, present.sql, present.params),
|
|
144
|
+
step(`ensure no NULL values in "${columnName}"`, noNulls.sql, noNulls.params),
|
|
151
145
|
],
|
|
152
146
|
execute: [
|
|
153
147
|
step(
|
|
@@ -156,49 +150,44 @@ export function setNotNull(schemaName: string, tableName: string, columnName: st
|
|
|
156
150
|
),
|
|
157
151
|
],
|
|
158
152
|
postcheck: [
|
|
159
|
-
step(
|
|
160
|
-
`verify column "${columnName}" is NOT NULL`,
|
|
161
|
-
columnNullabilityCheck({
|
|
162
|
-
schema: schemaName,
|
|
163
|
-
table: tableName,
|
|
164
|
-
column: columnName,
|
|
165
|
-
nullable: false,
|
|
166
|
-
}),
|
|
167
|
-
),
|
|
153
|
+
step(`verify column "${columnName}" is NOT NULL`, notNullable.sql, notNullable.params),
|
|
168
154
|
],
|
|
169
155
|
};
|
|
170
156
|
}
|
|
171
157
|
|
|
172
|
-
export function dropNotNull(
|
|
158
|
+
export async function dropNotNull(
|
|
159
|
+
schemaName: string,
|
|
160
|
+
tableName: string,
|
|
161
|
+
columnName: string,
|
|
162
|
+
lowerer: ExecuteRequestLowerer,
|
|
163
|
+
): Promise<Op> {
|
|
173
164
|
const qualified = qualifyTableName(schemaName, tableName);
|
|
165
|
+
const { present } = await columnExistsSteps(lowerer, {
|
|
166
|
+
schema: schemaName,
|
|
167
|
+
table: tableName,
|
|
168
|
+
column: columnName,
|
|
169
|
+
});
|
|
170
|
+
const nullable = await lowerer.lowerToExecuteRequest(
|
|
171
|
+
columnNullabilityAst({
|
|
172
|
+
schema: schemaName,
|
|
173
|
+
table: tableName,
|
|
174
|
+
column: columnName,
|
|
175
|
+
nullable: true,
|
|
176
|
+
}),
|
|
177
|
+
);
|
|
174
178
|
return {
|
|
175
179
|
id: `alterNullability.dropNotNull.${tableName}.${columnName}`,
|
|
176
180
|
label: `Drop NOT NULL on "${tableName}"."${columnName}"`,
|
|
177
181
|
operationClass: 'widening',
|
|
178
182
|
target: targetDetails('column', columnName, schemaName, tableName),
|
|
179
|
-
precheck: [
|
|
180
|
-
step(
|
|
181
|
-
`ensure column "${columnName}" exists`,
|
|
182
|
-
columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),
|
|
183
|
-
),
|
|
184
|
-
],
|
|
183
|
+
precheck: [step(`ensure column "${columnName}" exists`, present.sql, present.params)],
|
|
185
184
|
execute: [
|
|
186
185
|
step(
|
|
187
186
|
`drop NOT NULL on "${columnName}"`,
|
|
188
187
|
`ALTER TABLE ${qualified} ALTER COLUMN ${quoteIdentifier(columnName)} DROP NOT NULL`,
|
|
189
188
|
),
|
|
190
189
|
],
|
|
191
|
-
postcheck: [
|
|
192
|
-
step(
|
|
193
|
-
`verify column "${columnName}" is nullable`,
|
|
194
|
-
columnNullabilityCheck({
|
|
195
|
-
schema: schemaName,
|
|
196
|
-
table: tableName,
|
|
197
|
-
column: columnName,
|
|
198
|
-
nullable: true,
|
|
199
|
-
}),
|
|
200
|
-
),
|
|
201
|
-
],
|
|
190
|
+
postcheck: [step(`verify column "${columnName}" is nullable`, nullable.sql, nullable.params)],
|
|
202
191
|
};
|
|
203
192
|
}
|
|
204
193
|
|
|
@@ -212,25 +201,29 @@ export function dropNotNull(schemaName: string, tableName: string, columnName: s
|
|
|
212
201
|
* when the column already has a different default — policy enforcement
|
|
213
202
|
* treats that as a widening change rather than an additive one.
|
|
214
203
|
*/
|
|
215
|
-
export function setDefault(
|
|
204
|
+
export async function setDefault(
|
|
216
205
|
schemaName: string,
|
|
217
206
|
tableName: string,
|
|
218
207
|
columnName: string,
|
|
219
208
|
defaultSql: string,
|
|
209
|
+
lowerer: ExecuteRequestLowerer,
|
|
220
210
|
operationClass: 'additive' | 'widening' = 'additive',
|
|
221
|
-
): Op {
|
|
211
|
+
): Promise<Op> {
|
|
222
212
|
const qualified = qualifyTableName(schemaName, tableName);
|
|
213
|
+
const { present } = await columnExistsSteps(lowerer, {
|
|
214
|
+
schema: schemaName,
|
|
215
|
+
table: tableName,
|
|
216
|
+
column: columnName,
|
|
217
|
+
});
|
|
218
|
+
const hasDefault = await lowerer.lowerToExecuteRequest(
|
|
219
|
+
columnDefaultAst({ schema: schemaName, table: tableName, column: columnName }).defaultPresent(),
|
|
220
|
+
);
|
|
223
221
|
return {
|
|
224
222
|
id: `setDefault.${tableName}.${columnName}`,
|
|
225
223
|
label: `Set default on "${tableName}"."${columnName}"`,
|
|
226
224
|
operationClass,
|
|
227
225
|
target: targetDetails('column', columnName, schemaName, tableName),
|
|
228
|
-
precheck: [
|
|
229
|
-
step(
|
|
230
|
-
`ensure column "${columnName}" exists`,
|
|
231
|
-
columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),
|
|
232
|
-
),
|
|
233
|
-
],
|
|
226
|
+
precheck: [step(`ensure column "${columnName}" exists`, present.sql, present.params)],
|
|
234
227
|
execute: [
|
|
235
228
|
step(
|
|
236
229
|
`set default on "${columnName}"`,
|
|
@@ -238,32 +231,32 @@ export function setDefault(
|
|
|
238
231
|
),
|
|
239
232
|
],
|
|
240
233
|
postcheck: [
|
|
241
|
-
step(
|
|
242
|
-
`verify column "${columnName}" has a default`,
|
|
243
|
-
columnDefaultExistsCheck({
|
|
244
|
-
schema: schemaName,
|
|
245
|
-
table: tableName,
|
|
246
|
-
column: columnName,
|
|
247
|
-
exists: true,
|
|
248
|
-
}),
|
|
249
|
-
),
|
|
234
|
+
step(`verify column "${columnName}" has a default`, hasDefault.sql, hasDefault.params),
|
|
250
235
|
],
|
|
251
236
|
};
|
|
252
237
|
}
|
|
253
238
|
|
|
254
|
-
export function dropDefault(
|
|
239
|
+
export async function dropDefault(
|
|
240
|
+
schemaName: string,
|
|
241
|
+
tableName: string,
|
|
242
|
+
columnName: string,
|
|
243
|
+
lowerer: ExecuteRequestLowerer,
|
|
244
|
+
): Promise<Op> {
|
|
255
245
|
const qualified = qualifyTableName(schemaName, tableName);
|
|
246
|
+
const { present } = await columnExistsSteps(lowerer, {
|
|
247
|
+
schema: schemaName,
|
|
248
|
+
table: tableName,
|
|
249
|
+
column: columnName,
|
|
250
|
+
});
|
|
251
|
+
const noDefault = await lowerer.lowerToExecuteRequest(
|
|
252
|
+
columnDefaultAst({ schema: schemaName, table: tableName, column: columnName }).defaultAbsent(),
|
|
253
|
+
);
|
|
256
254
|
return {
|
|
257
255
|
id: `dropDefault.${tableName}.${columnName}`,
|
|
258
256
|
label: `Drop default on "${tableName}"."${columnName}"`,
|
|
259
257
|
operationClass: 'destructive',
|
|
260
258
|
target: targetDetails('column', columnName, schemaName, tableName),
|
|
261
|
-
precheck: [
|
|
262
|
-
step(
|
|
263
|
-
`ensure column "${columnName}" exists`,
|
|
264
|
-
columnExistsCheck({ schema: schemaName, table: tableName, column: columnName }),
|
|
265
|
-
),
|
|
266
|
-
],
|
|
259
|
+
precheck: [step(`ensure column "${columnName}" exists`, present.sql, present.params)],
|
|
267
260
|
execute: [
|
|
268
261
|
step(
|
|
269
262
|
`drop default on "${columnName}"`,
|
|
@@ -271,15 +264,57 @@ export function dropDefault(schemaName: string, tableName: string, columnName: s
|
|
|
271
264
|
),
|
|
272
265
|
],
|
|
273
266
|
postcheck: [
|
|
267
|
+
step(`verify column "${columnName}" has no default`, noDefault.sql, noDefault.params),
|
|
268
|
+
],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Builds the op for adding a NOT NULL column (no contract default) to a
|
|
274
|
+
* non-empty table. Prechecks assert the column is absent and the table is
|
|
275
|
+
* empty; the execute step is the raw ADD COLUMN SQL passed by the caller
|
|
276
|
+
* (slice-7 deferred); postchecks assert the column exists and is NOT NULL.
|
|
277
|
+
*/
|
|
278
|
+
export async function addNotNullColumnDirect(
|
|
279
|
+
schemaName: string,
|
|
280
|
+
tableName: string,
|
|
281
|
+
columnName: string,
|
|
282
|
+
executeStepSql: string,
|
|
283
|
+
lowerer: ExecuteRequestLowerer,
|
|
284
|
+
): Promise<Op> {
|
|
285
|
+
const absent = await lowerer.lowerToExecuteRequest(
|
|
286
|
+
columnExistsAst({ schema: schemaName, table: tableName, column: columnName }).columnAbsent(),
|
|
287
|
+
);
|
|
288
|
+
const tableEmpty = await lowerer.lowerToExecuteRequest(tableIsEmptyAst(schemaName, tableName));
|
|
289
|
+
const present = await lowerer.lowerToExecuteRequest(
|
|
290
|
+
columnExistsAst({ schema: schemaName, table: tableName, column: columnName }).columnPresent(),
|
|
291
|
+
);
|
|
292
|
+
const notNullable = await lowerer.lowerToExecuteRequest(
|
|
293
|
+
columnNullabilityAst({
|
|
294
|
+
schema: schemaName,
|
|
295
|
+
table: tableName,
|
|
296
|
+
column: columnName,
|
|
297
|
+
nullable: false,
|
|
298
|
+
}),
|
|
299
|
+
);
|
|
300
|
+
return {
|
|
301
|
+
id: `column.${tableName}.${columnName}`,
|
|
302
|
+
label: `Add column ${columnName} to ${tableName}`,
|
|
303
|
+
summary: `Adds column ${columnName} to table ${tableName}`,
|
|
304
|
+
operationClass: 'additive',
|
|
305
|
+
target: targetDetails('column', columnName, schemaName, tableName),
|
|
306
|
+
precheck: [
|
|
307
|
+
step(`ensure column "${columnName}" is missing`, absent.sql, absent.params),
|
|
274
308
|
step(
|
|
275
|
-
`
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
table: tableName,
|
|
279
|
-
column: columnName,
|
|
280
|
-
exists: false,
|
|
281
|
-
}),
|
|
309
|
+
`ensure table "${tableName}" is empty before adding NOT NULL column without default`,
|
|
310
|
+
tableEmpty.sql,
|
|
311
|
+
tableEmpty.params,
|
|
282
312
|
),
|
|
283
313
|
],
|
|
314
|
+
execute: [step(`add column "${columnName}"`, executeStepSql)],
|
|
315
|
+
postcheck: [
|
|
316
|
+
step(`verify column "${columnName}" exists`, present.sql, present.params),
|
|
317
|
+
step(`verify column "${columnName}" is NOT NULL`, notNullable.sql, notNullable.params),
|
|
318
|
+
],
|
|
284
319
|
};
|
|
285
320
|
}
|