Repository: diesel-rs/diesel (language: rust)

Issue:
Name colission in `table!` macro with `is_nullable` column
### Discussed in https://github.com/diesel-rs/diesel/discussions/3403

<div type='discussions-op-text'>

<sup>Originally posted by **forest1102** November 11, 2022</sup>
Hello, I am trying to update diesel 2.0, and I have a problem with a table that has an `is_nullable` column.  
Even though by adding `sql_name` attribute helps, I have to modify the schema file every time I changed the schema file. 
Suppose I made a migration file like below. 

```sql
create table db_definition_items
(
    id bigserial primary key,
    is_nullable boolean not null
);
```
and after `diesel database reset`, it will produce table schema below. 

```rs
diesel::table! {
    db_definition_items (id) {
        id -> Int8,
        is_nullable -> Bool,
    }
}
```

But this code has an error saying, 
```
`is_nullable` is ambiguous
ambiguous because of multiple glob imports of a name in the same module
consider adding an explicit import of `is_nullable` to disambiguate
consider adding an explicit import of `is_nullable` to disambiguate
```

How can I suppress this error?

## versions

```bash
$ rustc -V         
rustc 1.65.0 (897e37553 2022-11-02)

$ diesel --version
diesel 2.0.1
```

### Cargo.toml

```Cargo.toml
[package]
name = "serve"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
diesel = "2.0.2"
```</div>


Discussion / hints:
This is caused by the export of [`is_nullable` in the `diesel::sql_types` module](https://docs.diesel.rs/master/diesel/sql_types/is_nullable/index.html). Removing this export is not possible.

This problem should be fixed in diesel_cli by adding `is_nullable` to the list of reserved names here: https://github.com/diesel-rs/diesel/blob/027be9b155a3439ede6c947bd1de30cd8954c3c4/diesel_cli/src/infer_schema_internals/inference.rs#L10

In addition we might want to add a test for that [here](https://github.com/diesel-rs/diesel/blob/027be9b155a3439ede6c947bd1de30cd8954c3c4/diesel_cli/tests/print_schema.rs). 

@forest1102 mind opening a PR for that?

Yes, please.

Fix patch:
diff --git a/diesel_bench/Cargo.toml b/diesel_bench/Cargo.toml
index 7fb85129eab0..888ea1dbf1b4 100644
--- a/diesel_bench/Cargo.toml
+++ b/diesel_bench/Cargo.toml
@@ -15,7 +15,7 @@ sqlx = {version = "0.6", features = ["runtime-tokio-rustls"], optional = true}
 tokio = {version = "1", optional = true}
 rusqlite = {version = "0.27", optional = true}
 rust_postgres = {version = "0.19", optional = true, package = "postgres"}
-rust_mysql = {version = "22.1", optional = true, package = "mysql"}
+rust_mysql = {version = "23.0", optional = true, package = "mysql"}
 rustorm = {version = "0.20", optional = true}
 rustorm_dao = {version = "0.20", optional = true}
 quaint = {version = "=0.2.0-alpha.13", optional = true, features = ["uuid"]}
diff --git a/diesel_cli/src/infer_schema_internals/inference.rs b/diesel_cli/src/infer_schema_internals/inference.rs
index 3d04bd9c7adf..87d7680343cd 100644
--- a/diesel_cli/src/infer_schema_internals/inference.rs
+++ b/diesel_cli/src/infer_schema_internals/inference.rs
@@ -8,12 +8,61 @@ use crate::database::InferConnection;
 use crate::print_schema::ColumnSorting;
 
 static RESERVED_NAMES: &[&str] = &[
-    "abstract", "alignof", "as", "become", "box", "break", "const", "continue", "crate", "do",
-    "else", "enum", "extern", "false", "final", "fn", "for", "if", "impl", "in", "let", "loop",
-    "macro", "match", "mod", "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
-    "ref", "return", "Self", "self", "sizeof", "static", "struct", "super", "trait", "true",
-    "type", "typeof", "unsafe", "unsized", "use", "virtual", "where", "while", "yield", "bool",
+    "abstract",
+    "alignof",
+    "as",
+    "become",
+    "box",
+    "break",
+    "const",
+    "continue",
+    "crate",
+    "do",
+    "else",
+    "enum",
+    "extern",
+    "false",
+    "final",
+    "fn",
+    "for",
+    "if",
+    "impl",
+    "in",
+    "let",
+    "loop",
+    "macro",
+    "match",
+    "mod",
+    "move",
+    "mut",
+    "offsetof",
+    "override",
+    "priv",
+    "proc",
+    "pub",
+    "pure",
+    "ref",
+    "return",
+    "Self",
+    "self",
+    "sizeof",
+    "static",
+    "struct",
+    "super",
+    "trait",
+    "true",
+    "type",
+    "typeof",
+    "unsafe",
+    "unsized",
+    "use",
+    "virtual",
+    "where",
+    "while",
+    "yield",
+    "bool",
     "columns",
+    "is_nullable",
 ];
 
 fn is_reserved_name(name: &str) -> bool {


Test patch:
diff --git a/diesel_cli/tests/print_schema.rs b/diesel_cli/tests/print_schema.rs
index 4ac5825ac1c9..6ff32e51aba1 100644
--- a/diesel_cli/tests/print_schema.rs
+++ b/diesel_cli/tests/print_schema.rs
@@ -265,6 +265,11 @@ fn print_schema_comments() {
     test_print_schema("print_schema_comments", vec!["--with-docs"])
 }
 
+#[test]
+fn print_schema_reserved_names() {
+    test_print_schema("print_schema_reserved_name_mitigation_issue_3404", vec![])
+}
+
 #[cfg(feature = "sqlite")]
 const BACKEND: &str = "sqlite";
 #[cfg(feature = "postgres")]
diff --git a/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/diesel.toml b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/diesel.toml
new file mode 100644
index 000000000000..3985231b860a
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/diesel.toml
@@ -0,0 +1,3 @@
+[print_schema]
+file = "src/schema.rs"
+with_docs = false
diff --git a/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/mysql/expected.snap b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/mysql/expected.snap
new file mode 100644
index 000000000000..4f301590c57f
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/mysql/expected.snap
@@ -0,0 +1,14 @@
+---
+source: diesel_cli/tests/print_schema.rs
+description: "Test: print_schema_reserved_name_mitigation_issue_3404"
+---
+// @generated automatically by Diesel CLI.
+
+diesel::table! {
+    reserved_names_columns (id) {
+        id -> Integer,
+        #[sql_name = "is_nullable"]
+        is_nullable_ -> Nullable<Bool>,
+    }
+}
+
diff --git a/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/mysql/schema.sql b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/mysql/schema.sql
new file mode 100644
index 000000000000..95481505775b
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/mysql/schema.sql
@@ -0,0 +1,5 @@
+CREATE TABLE reserved_names_columns
+(
+    id          INTEGER PRIMARY KEY,
+    is_nullable BOOLEAN
+);
diff --git a/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/postgres/expected.snap b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/postgres/expected.snap
new file mode 100644
index 000000000000..53a14572b8a7
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/postgres/expected.snap
@@ -0,0 +1,14 @@
+---
+source: diesel_cli/tests/print_schema.rs
+description: "Test: print_schema_reserved_name_mitigation_issue_3404"
+---
+// @generated automatically by Diesel CLI.
+
+diesel::table! {
+    reserved_names_columns (id) {
+        id -> Int4,
+        #[sql_name = "is_nullable"]
+        is_nullable_ -> Nullable<Bool>,
+    }
+}
+
diff --git a/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/postgres/schema.sql b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/postgres/schema.sql
new file mode 100644
index 000000000000..eaeb462e3ded
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/postgres/schema.sql
@@ -0,0 +1,5 @@
+CREATE TABLE reserved_names_columns
+(
+    id SERIAL PRIMARY KEY,
+    is_nullable BOOLEAN
+);
diff --git a/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/sqlite/expected.snap b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/sqlite/expected.snap
new file mode 100644
index 000000000000..c970c8cb06bf
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/sqlite/expected.snap
@@ -0,0 +1,14 @@
+---
+source: diesel_cli/tests/print_schema.rs
+description: "Test: print_schema_reserved_name_mitigation_issue_3404"
+---
+// @generated automatically by Diesel CLI.
+
+diesel::table! {
+    reserved_names_columns (id) {
+        id -> Nullable<Integer>,
+        #[sql_name = "is_nullable"]
+        is_nullable_ -> Nullable<Bool>,
+    }
+}
+
diff --git a/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/sqlite/schema.sql b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/sqlite/schema.sql
new file mode 100644
index 000000000000..95481505775b
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_reserved_name_mitigation_issue_3404/sqlite/schema.sql
@@ -0,0 +1,5 @@
+CREATE TABLE reserved_names_columns
+(
+    id          INTEGER PRIMARY KEY,
+    is_nullable BOOLEAN
+);