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

Issue:
Diesel 2.0: Wrong `postgres_type` naming
## Setup

### Versions
- **Rust:** Latest
- **Diesel:** 2.0
- **Database:** PostgreSQL
- **Operating System:** Linux

### Feature Flags
- **diesel:** postgres

## Problem Description
When there is a custom type, which it's name contains capital letters. The generated name in the `schema.rs` file will be in lower case, like the following example:

```
pub mod sql_types {
    #[derive(diesel::sql_types::SqlType)]
    #[diesel(postgres_type(name = "poststatus"))]
    pub struct PostStatus;
}
```

In this case, inserting a row (it needs to contain the custom type), will return an error like this:
```
thread 'main' panicked at 'Error saving new post: SerializationError(FailedToLookupTypeError(PgMetadataCacheKey { schema: None, type_name: "poststatus" }))', src/lib.rs:30:10
```

postgres also reports this:
```
ERROR:  type "poststatus" does not exist
STATEMENT:  SELECT "pg_type"."oid", "pg_type"."typarray" FROM "pg_type" WHERE ("pg_type"."oid" = quote_ident($1)::regtype::oid) LIMIT $2
```

The same can happen for other queries, like select by the custom type, or update or so on.

### Steps to reproduce
- Clone this sample project: https://github.com/omid/diesel_demo
- Run postgresql
- Configure `.env` file
- Run `make`, then you will see the error
- It will work if you go to `schema.rs` and change `poststatus` to `PostStatus`, and run `cargo run --bin write_post`



Discussion / hints:
This would probably be the issue:
https://github.com/diesel-rs/diesel/blob/cb185429d1ed8550f25615e84c14534692da8bda/diesel_cli/src/infer_schema_internals/pg.rs#L46

And there's the same on the mysql side:
https://github.com/diesel-rs/diesel/blob/cb185429d1ed8550f25615e84c14534692da8bda/diesel_cli/src/infer_schema_internals/mysql.rs#L155

@weiznich any particular reason why there is a to_lowercase call here or should we just remove them?
> @weiznich any particular reason why there is a to_lowercase call here or should we just remove them?

I cannot remember a particular reason for this + this seems to cause this bug. Removing the `.to_lowercase()` call in the postgres implementation should be fine as long as all tests continue to pass. @omid Mind filling a PR for this which removes the call + adds something like your type definition as test case?
@weiznich sure, will try my best

Fix patch:
diff --git a/diesel_cli/src/infer_schema_internals/mysql.rs b/diesel_cli/src/infer_schema_internals/mysql.rs
index e75a95907552..8ed5822bd938 100644
--- a/diesel_cli/src/infer_schema_internals/mysql.rs
+++ b/diesel_cli/src/infer_schema_internals/mysql.rs
@@ -152,7 +152,7 @@ pub fn determine_column_type(
 
     Ok(ColumnType {
         schema: None,
-        sql_name: tpe.trim().to_lowercase(),
+        sql_name: tpe.trim().to_string(),
         rust_name: tpe.trim().to_upper_camel_case(),
         is_array: false,
         is_nullable: attr.nullable,
diff --git a/diesel_cli/src/infer_schema_internals/pg.rs b/diesel_cli/src/infer_schema_internals/pg.rs
index 6e76722cf135..b7c4021cbb0d 100644
--- a/diesel_cli/src/infer_schema_internals/pg.rs
+++ b/diesel_cli/src/infer_schema_internals/pg.rs
@@ -43,7 +43,7 @@ pub fn determine_column_type(
                 Some(s.clone())
             }
         }),
-        sql_name: tpe.to_lowercase(),
+        sql_name: tpe.to_string(),
         rust_name: tpe.to_upper_camel_case(),
         is_array,
         is_nullable: attr.nullable,


Test patch:
diff --git a/diesel_cli/tests/print_schema.rs b/diesel_cli/tests/print_schema.rs
index 026c387525fd..9486b77b9453 100644
--- a/diesel_cli/tests/print_schema.rs
+++ b/diesel_cli/tests/print_schema.rs
@@ -229,6 +229,12 @@ fn print_schema_sqlite_implicit_foreign_key_reference() {
     test_print_schema("print_schema_sqlite_implicit_foreign_key_reference", vec![]);
 }
 
+#[test]
+#[cfg(feature = "postgres")]
+fn print_schema_respects_type_name_case() {
+    test_print_schema("print_schema_respects_type_name_case", vec!["--with-docs"])
+}
+
 #[test]
 #[cfg(any(feature = "postgres", feature = "mysql"))]
 fn print_schema_comments() {
diff --git a/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/diesel.toml b/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/diesel.toml
new file mode 100644
index 000000000000..750e5ba85830
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/diesel.toml
@@ -0,0 +1,3 @@
+[print_schema]
+file = "src/schema.rs"
+with_docs = true
diff --git a/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/postgres/expected.rs b/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/postgres/expected.rs
new file mode 100644
index 000000000000..e0c58fabfec8
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/postgres/expected.rs
@@ -0,0 +1,56 @@
+// @generated automatically by Diesel CLI.
+
+/// A module containing custom SQL type definitions
+///
+/// (Automatically generated by Diesel.)
+pub mod sql_types {
+    /// The `MyType` SQL type
+    ///
+    /// (Automatically generated by Diesel.)
+    #[derive(diesel::sql_types::SqlType)]
+    #[diesel(postgres_type(name = "MyType"))]
+    pub struct MyType;
+
+    /// The `MyType2` SQL type
+    ///
+    /// (Automatically generated by Diesel.)
+    #[derive(diesel::sql_types::SqlType)]
+    #[diesel(postgres_type(name = "MyType2"))]
+    pub struct MyType2;
+}
+
+diesel::table! {
+    use diesel::sql_types::*;
+    use super::sql_types::MyType;
+    use super::sql_types::MyType2;
+
+    /// Representation of the `custom_types` table.
+    ///
+    /// (Automatically generated by Diesel.)
+    custom_types (id) {
+        /// The `id` column of the `custom_types` table.
+        ///
+        /// Its SQL type is `Int4`.
+        ///
+        /// (Automatically generated by Diesel.)
+        id -> Int4,
+        /// The `custom_enum` column of the `custom_types` table.
+        ///
+        /// Its SQL type is `MyType`.
+        ///
+        /// (Automatically generated by Diesel.)
+        custom_enum -> MyType,
+        /// The `custom_enum_nullable` column of the `custom_types` table.
+        ///
+        /// Its SQL type is `Nullable<MyType>`.
+        ///
+        /// (Automatically generated by Diesel.)
+        custom_enum_nullable -> Nullable<MyType>,
+        /// The `custom_enum2` column of the `custom_types` table.
+        ///
+        /// Its SQL type is `MyType2`.
+        ///
+        /// (Automatically generated by Diesel.)
+        custom_enum2 -> MyType2,
+    }
+}
diff --git a/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/postgres/schema.sql b/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/postgres/schema.sql
new file mode 100644
index 000000000000..becbb2634e98
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_respects_type_name_case/postgres/schema.sql
@@ -0,0 +1,8 @@
+CREATE TYPE "MyType" AS ENUM ('foo', 'bar');
+CREATE TYPE "MyType2" AS ENUM ('foo', 'bar');
+CREATE TABLE custom_types (
+    id SERIAL PRIMARY KEY,
+    custom_enum "MyType" NOT NULL,
+    custom_enum_nullable "MyType",
+    custom_enum2 "MyType2" NOT NULL
+);