Skip to content

Commit 2eb27c0

Browse files
authored
feat: do not render default namespace not specified in schema (#5614)
[ORM-1381](https://linear.app/prisma-company/issue/ORM-1381/timeboxresearch-support-migrations-without-explicit-schema-again) Fixes prisma/prisma#27811 This PR creates a distinction between the default runtime namespace and the namespaces specified in the schema file. `explicit_namespace` refers to namespace that's been made explicit in the schema file and `namespace` refers to the namespace the table or enum will effectively belong to at runtime. The reason for this distinction is to enable us to correctly recognize that: - the effective namespace of a table or an enum has not changed during diffing (it uses `namespace`) - the namespace of a table or an enum should not be rendered (it uses `explicit_namespace`)
1 parent 7094b62 commit 2eb27c0

35 files changed

+260
-247
lines changed

schema-engine/connectors/sql-schema-connector/src/apply_migration.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ fn render_raw_sql(
149149
SqlMigrationStep::DropTable { table_id } => {
150150
let table = schemas.previous.walk(*table_id);
151151

152-
renderer.render_drop_table(table.namespace(), table.name())
152+
renderer.render_drop_table(table.explicit_namespace(), table.name())
153153
}
154154
SqlMigrationStep::RedefineIndex { index } => renderer.render_drop_and_recreate_index(schemas.walk(*index)),
155155
SqlMigrationStep::AddForeignKey { foreign_key_id } => {

schema-engine/connectors/sql-schema-connector/src/flavour/mssql/destructive_change_checker.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl DestructiveChangeCheckerFlavour for MssqlDestructiveChangeCheckerFlavour {
5858
plan.push_unexecutable(
5959
UnexecutableStepCheck::MadeOptionalFieldRequired(Column {
6060
table: columns.previous.table().name().to_owned(),
61-
namespace: columns.previous.table().namespace().map(str::to_owned),
61+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
6262
column: columns.previous.name().to_owned(),
6363
}),
6464
step_index,
@@ -76,7 +76,7 @@ impl DestructiveChangeCheckerFlavour for MssqlDestructiveChangeCheckerFlavour {
7676
plan.push_warning(
7777
SqlMigrationWarningCheck::RiskyCast {
7878
table: columns.previous.table().name().to_owned(),
79-
namespace: columns.previous.table().namespace().map(str::to_owned),
79+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
8080
column: columns.previous.name().to_owned(),
8181
previous_type,
8282
next_type,
@@ -88,7 +88,7 @@ impl DestructiveChangeCheckerFlavour for MssqlDestructiveChangeCheckerFlavour {
8888
plan.push_warning(
8989
SqlMigrationWarningCheck::NotCastable {
9090
table: columns.previous.table().name().to_owned(),
91-
namespace: columns.previous.table().namespace().map(str::to_owned),
91+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
9292
column: columns.previous.name().to_owned(),
9393
previous_type: format!("{:?}", columns.previous.column_type_family()),
9494
next_type: format!("{:?}", columns.next.column_type_family()),
@@ -115,7 +115,7 @@ impl DestructiveChangeCheckerFlavour for MssqlDestructiveChangeCheckerFlavour {
115115
plan.push_unexecutable(
116116
UnexecutableStepCheck::AddedRequiredFieldToTable(Column {
117117
table: columns.previous.table().name().to_owned(),
118-
namespace: columns.previous.table().namespace().map(str::to_owned),
118+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
119119
column: columns.previous.name().to_owned(),
120120
}),
121121
step_index,
@@ -124,7 +124,7 @@ impl DestructiveChangeCheckerFlavour for MssqlDestructiveChangeCheckerFlavour {
124124
plan.push_unexecutable(
125125
UnexecutableStepCheck::DropAndRecreateRequiredColumn(Column {
126126
table: columns.previous.table().name().to_owned(),
127-
namespace: columns.previous.table().namespace().map(str::to_owned),
127+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
128128
column: columns.previous.name().to_owned(),
129129
}),
130130
step_index,
@@ -134,7 +134,7 @@ impl DestructiveChangeCheckerFlavour for MssqlDestructiveChangeCheckerFlavour {
134134
SqlMigrationWarningCheck::DropAndRecreateColumn {
135135
column: columns.previous.name().to_owned(),
136136
table: columns.previous.table().name().to_owned(),
137-
namespace: columns.previous.table().namespace().map(str::to_owned),
137+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
138138
},
139139
step_index,
140140
)

schema-engine/connectors/sql-schema-connector/src/flavour/mssql/renderer.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ impl MssqlRenderer {
2929
fn table_name<'a>(&'a self, table: sql::TableWalker<'a>) -> QuotedWithPrefix<&'a str> {
3030
QuotedWithPrefix(
3131
Some(Quoted::mssql_ident(
32-
table.namespace().unwrap_or_else(|| self.schema_name()),
32+
table.explicit_namespace().unwrap_or_else(|| self.schema_name()),
3333
)),
3434
Quoted::mssql_ident(table.name()),
3535
)
@@ -109,7 +109,7 @@ impl SqlRenderer for MssqlRenderer {
109109
indexes
110110
.previous
111111
.table()
112-
.namespace()
112+
.explicit_namespace()
113113
.unwrap_or_else(|| &self.schema_name),
114114
indexes.previous.table().name(),
115115
indexes.previous.name()
@@ -318,12 +318,12 @@ impl SqlRenderer for MssqlRenderer {
318318
EXEC sp_executesql @SQL
319319
"#,
320320
table = tables.previous.name(),
321-
schema = tables.previous.namespace().unwrap_or_else(|| self.schema_name())});
321+
schema = tables.previous.explicit_namespace().unwrap_or_else(|| self.schema_name())});
322322

323323
// Create the new table.
324324
result.push(self.render_create_table_as(
325325
tables.next,
326-
self.quote_with_schema(tables.next.namespace(), &temporary_table_name),
326+
self.quote_with_schema(tables.next.explicit_namespace(), &temporary_table_name),
327327
));
328328

329329
// We cannot insert into autoincrement columns by default. If we
@@ -332,7 +332,7 @@ impl SqlRenderer for MssqlRenderer {
332332
if needs_autoincrement {
333333
result.push(format!(
334334
r#"SET IDENTITY_INSERT {} ON"#,
335-
self.quote_with_schema(tables.next.namespace(), &temporary_table_name)
335+
self.quote_with_schema(tables.next.explicit_namespace(), &temporary_table_name)
336336
));
337337
}
338338

@@ -342,22 +342,26 @@ impl SqlRenderer for MssqlRenderer {
342342
EXEC('INSERT INTO {tmp_table} ({columns}) SELECT {columns} FROM {table} WITH (holdlock tablockx)')"#,
343343
columns = columns.join(","),
344344
table = self.table_name(tables.previous),
345-
tmp_table = self.quote_with_schema(tables.next.namespace(), &temporary_table_name),
345+
tmp_table = self.quote_with_schema(tables.next.explicit_namespace(), &temporary_table_name),
346346
});
347347

348348
// When done copying, disallow identity inserts again if needed.
349349
if needs_autoincrement {
350350
result.push(format!(
351351
r#"SET IDENTITY_INSERT {} OFF"#,
352-
self.quote_with_schema(tables.next.namespace(), &temporary_table_name)
352+
self.quote_with_schema(tables.next.explicit_namespace(), &temporary_table_name)
353353
));
354354
}
355355

356356
// Drop the old, now empty table.
357-
result.extend(self.render_drop_table(tables.previous.namespace(), tables.previous.name()));
357+
result.extend(self.render_drop_table(tables.previous.explicit_namespace(), tables.previous.name()));
358358

359359
// Rename the temporary table with the name defined in the migration.
360-
result.push(self.render_rename_table(tables.next.namespace(), &temporary_table_name, tables.next.name()));
360+
result.push(self.render_rename_table(
361+
tables.next.explicit_namespace(),
362+
&temporary_table_name,
363+
tables.next.name(),
364+
));
361365

362366
// Recreate the indexes.
363367
for index in tables.next.indexes().filter(|i| !i.is_unique() && !i.is_primary_key()) {
@@ -470,7 +474,11 @@ impl SqlRenderer for MssqlRenderer {
470474
fn render_rename_foreign_key(&self, fks: MigrationPair<sql::ForeignKeyWalker<'_>>) -> String {
471475
format!(
472476
r#"EXEC sp_rename '{schema}.{previous}', '{next}', 'OBJECT'"#,
473-
schema = fks.previous.table().namespace().unwrap_or_else(|| self.schema_name()),
477+
schema = fks
478+
.previous
479+
.table()
480+
.explicit_namespace()
481+
.unwrap_or_else(|| self.schema_name()),
474482
previous = fks.previous.constraint_name().unwrap(),
475483
next = fks.next.constraint_name().unwrap(),
476484
)

schema-engine/connectors/sql-schema-connector/src/flavour/mssql/renderer/alter_table.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl AlterTableConstructor<'_> {
9898
"{}.{}",
9999
self.tables
100100
.previous
101-
.namespace()
101+
.explicit_namespace()
102102
.unwrap_or_else(|| self.renderer.schema_name()),
103103
self.tables.previous.primary_key().unwrap().name()
104104
);

schema-engine/connectors/sql-schema-connector/src/flavour/mysql/destructive_change_checker.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl DestructiveChangeCheckerFlavour for MysqlDestructiveChangeCheckerFlavour {
5252
plan.push_unexecutable(
5353
UnexecutableStepCheck::MadeOptionalFieldRequired(Column {
5454
table: columns.previous.table().name().to_owned(),
55-
namespace: columns.previous.table().namespace().map(str::to_owned),
55+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
5656
column: columns.previous.name().to_owned(),
5757
}),
5858
step_index,
@@ -74,7 +74,7 @@ impl DestructiveChangeCheckerFlavour for MysqlDestructiveChangeCheckerFlavour {
7474
plan.push_warning(
7575
SqlMigrationWarningCheck::RiskyCast {
7676
table: columns.previous.table().name().to_owned(),
77-
namespace: columns.previous.table().namespace().map(str::to_owned),
77+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
7878
column: columns.previous.name().to_owned(),
7979
previous_type,
8080
next_type,
@@ -86,7 +86,7 @@ impl DestructiveChangeCheckerFlavour for MysqlDestructiveChangeCheckerFlavour {
8686
plan.push_warning(
8787
SqlMigrationWarningCheck::NotCastable {
8888
table: columns.previous.table().name().to_owned(),
89-
namespace: columns.previous.table().namespace().map(str::to_owned),
89+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
9090
column: columns.previous.name().to_owned(),
9191
previous_type,
9292
next_type,
@@ -113,7 +113,7 @@ impl DestructiveChangeCheckerFlavour for MysqlDestructiveChangeCheckerFlavour {
113113
plan.push_unexecutable(
114114
UnexecutableStepCheck::AddedRequiredFieldToTable(Column {
115115
table: columns.previous.table().name().to_owned(),
116-
namespace: columns.previous.table().namespace().map(str::to_owned),
116+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
117117
column: columns.previous.name().to_owned(),
118118
}),
119119
step_index,
@@ -122,7 +122,7 @@ impl DestructiveChangeCheckerFlavour for MysqlDestructiveChangeCheckerFlavour {
122122
plan.push_unexecutable(
123123
UnexecutableStepCheck::DropAndRecreateRequiredColumn(Column {
124124
table: columns.previous.table().name().to_owned(),
125-
namespace: columns.previous.table().namespace().map(str::to_owned),
125+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
126126
column: columns.previous.name().to_owned(),
127127
}),
128128
step_index,
@@ -133,7 +133,7 @@ impl DestructiveChangeCheckerFlavour for MysqlDestructiveChangeCheckerFlavour {
133133
SqlMigrationWarningCheck::DropAndRecreateColumn {
134134
column: columns.previous.name().to_owned(),
135135
table: columns.previous.table().name().to_owned(),
136-
namespace: columns.previous.table().namespace().map(str::to_owned),
136+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
137137
},
138138
step_index,
139139
)

schema-engine/connectors/sql-schema-connector/src/flavour/postgres/destructive_change_checker.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl DestructiveChangeCheckerFlavour for PostgresDestructiveChangeCheckerFlavour
5555
plan.push_unexecutable(
5656
UnexecutableStepCheck::MadeOptionalFieldRequired(Column {
5757
table: columns.previous.table().name().to_owned(),
58-
namespace: columns.previous.table().namespace().map(str::to_owned),
58+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
5959
column: columns.previous.name().to_owned(),
6060
}),
6161
step_index,
@@ -66,7 +66,7 @@ impl DestructiveChangeCheckerFlavour for PostgresDestructiveChangeCheckerFlavour
6666
plan.push_unexecutable(
6767
UnexecutableStepCheck::MadeScalarFieldIntoArrayField(Column {
6868
table: columns.previous.table().name().to_owned(),
69-
namespace: columns.previous.table().namespace().map(str::to_owned),
69+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
7070
column: columns.previous.name().to_owned(),
7171
}),
7272
step_index,
@@ -82,7 +82,7 @@ impl DestructiveChangeCheckerFlavour for PostgresDestructiveChangeCheckerFlavour
8282
plan.push_warning(
8383
SqlMigrationWarningCheck::RiskyCast {
8484
table: columns.previous.table().name().to_owned(),
85-
namespace: columns.previous.table().namespace().map(String::from),
85+
namespace: columns.previous.table().explicit_namespace().map(String::from),
8686
column: columns.previous.name().to_owned(),
8787
previous_type,
8888
next_type,
@@ -94,7 +94,7 @@ impl DestructiveChangeCheckerFlavour for PostgresDestructiveChangeCheckerFlavour
9494
plan.push_warning(
9595
SqlMigrationWarningCheck::NotCastable {
9696
table: columns.previous.table().name().to_owned(),
97-
namespace: columns.previous.table().namespace().map(String::from),
97+
namespace: columns.previous.table().explicit_namespace().map(String::from),
9898
column: columns.previous.name().to_owned(),
9999
previous_type,
100100
next_type,
@@ -121,7 +121,7 @@ impl DestructiveChangeCheckerFlavour for PostgresDestructiveChangeCheckerFlavour
121121
plan.push_unexecutable(
122122
UnexecutableStepCheck::AddedRequiredFieldToTable(Column {
123123
table: columns.previous.table().name().to_owned(),
124-
namespace: columns.previous.table().namespace().map(str::to_owned),
124+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
125125
column: columns.previous.name().to_owned(),
126126
}),
127127
step_index,
@@ -130,7 +130,7 @@ impl DestructiveChangeCheckerFlavour for PostgresDestructiveChangeCheckerFlavour
130130
plan.push_unexecutable(
131131
UnexecutableStepCheck::DropAndRecreateRequiredColumn(Column {
132132
table: columns.previous.table().name().to_owned(),
133-
namespace: columns.previous.table().namespace().map(str::to_owned),
133+
namespace: columns.previous.table().explicit_namespace().map(str::to_owned),
134134
column: columns.previous.name().to_owned(),
135135
}),
136136
step_index,
@@ -140,7 +140,7 @@ impl DestructiveChangeCheckerFlavour for PostgresDestructiveChangeCheckerFlavour
140140
plan.push_warning(
141141
SqlMigrationWarningCheck::DropAndRecreateColumn {
142142
column: columns.previous.name().to_owned(),
143-
namespace: columns.previous.table().namespace().map(String::from),
143+
namespace: columns.previous.table().explicit_namespace().map(String::from),
144144
table: columns.previous.table().name().to_owned(),
145145
},
146146
step_index,

0 commit comments

Comments
 (0)