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

Issue:
ERROR: `relation "user" does not exist` while running `diesel migration/print-schema`
<!--
If you want to report a bug, we added some points below which help us track down the problem faster.
-->

## Setup
[My pg dump](https://gist.github.com/df51d/51e5ae9b2bb52ca40014f2235a7e8c55#file-pg_dump-sql)
### Versions

- **Rust:**
cargo 1.70.0 (ec8a8a0ca 2023-04-25)
rustc 1.70.0 (90c541806 2023-05-31)
- **Diesel:**
diesel 2.1.0
- **Database:**
postgresql 15.3-1.pgdg120+1
- **Operating System**
ArcoLinux kernel 6.3.8-arch1-1
### Feature Flags
```
cargo install diesel_cli --no-
default-features --features "postgres sqlite"
```
## Problem Description
I encountered an error while running `diesel print-schema`/`diesel migration run` on my old database after installing the diesel-cli. I was attempting to switch from a TypeScript project that utilized Prisma as the database driver to a Rust project with Diesel as the database driver. Since starting from scratch and recreating everything would be a significant amount of work, my intention was to reuse my existing database. However, I faced difficulties during the process. 
### What are you trying to accomplish?
```diesel print-schema```
### What is the actual output?
```relation "user" does not exist```
### Steps to reproduce
#### with prisma installed
```bash
docker pull postgres

docker run -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres

echo 'DATABASE_URL="postgresql://postgres:postgres@localhost:5432/db"' > .env

prisma init

echo 'model User {\n\tid Int @id @default(autoincrement())\n}' >> prisma/schema.prisma

prisma db push

diesel print-schema
```
#### without prisma installed
```bash
docker pull postgres

docker run -e POSTGRES_PASSWORD=postgres -p 5432:5432 -d postgres

echo 'DATABASE_URL="postgresql://postgres:postgres@localhost:5432/db"' > .env

diesel setup

mkdir migrations/user

echo "CREATE TABLE public.\"User\" (
    id integer NOT NULL
);
ALTER TABLE public.\"User\" OWNER TO postgres;
CREATE SEQUENCE public.\"User_id_seq\"
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;
ALTER TABLE public.\"User_id_seq\" OWNER TO postgres;
ALTER SEQUENCE public.\"User_id_seq\" OWNED BY public.\"User\".id;
ALTER TABLE ONLY public.\"User\" ALTER COLUMN id SET DEFAULT nextval('public.\"User_id_seq\"'::regclass);
SELECT pg_catalog.setval('public.\"User_id_seq\"', 1, false);
ALTER TABLE ONLY public.\"User\"
    ADD CONSTRAINT \"User_pkey\" PRIMARY KEY (id);" > migrations/user/up.sql
    
diesel migration run
```
### Temporary fix:
Making all tables lowercase seems to fix the problem:
#### working migration
```sql
--- this works just fine /migrations/user/up.sql
CREATE TABLE public."user" (
    id integer NOT NULL
);
ALTER TABLE public."user" OWNER TO postgres;
CREATE SEQUENCE public."user_id_seq"
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;
ALTER TABLE public."user_id_seq" OWNER TO postgres;
ALTER SEQUENCE public."user_id_seq" OWNED BY public."user".id;
ALTER TABLE ONLY public."user" ALTER COLUMN id SET DEFAULT nextval('public."user_id_seq"'::regclass);
SELECT pg_catalog.setval('public."user_id_seq"', 1, false);
ALTER TABLE ONLY public."user"
    ADD CONSTRAINT "user_pkey" PRIMARY KEY (id);
```
#### working prisma 
```prisma
model user {
  id Int @id @default(autoincrement())
}
```
## Checklist
- [x] I have already looked over the [issue tracker](https://github.com/diesel-rs/diesel/issues) and the [discussion forum](https://github.com/diesel-rs/diesel/discussions) for similar possible closed issues.
<!--
If you are unsure if your issue is a duplicate of an existing issue please link the issue in question here
--> 
- [x] This issue can be reproduced on Rust's stable channel. (Your issue will be
  closed if this is not the case)
- [x] This issue can be reproduced without requiring a third party crate


Discussion / hints:

Fix patch:
diff --git a/diesel_cli/src/infer_schema_internals/pg.rs b/diesel_cli/src/infer_schema_internals/pg.rs
index 03a6cc18a303..79a69133ae4a 100644
--- a/diesel_cli/src/infer_schema_internals/pg.rs
+++ b/diesel_cli/src/infer_schema_internals/pg.rs
@@ -61,8 +61,13 @@ pub fn determine_column_type(
 diesel::postfix_operator!(Regclass, "::regclass", sql_types::Oid, backend: Pg);
 
 fn regclass(table: &TableName) -> Regclass<AsExprOf<String, sql_types::Text>> {
+    let table_name = match table.schema {
+        Some(ref schema_name) => format!("\"{}\".\"{}\"", schema_name, table.sql_name),
+        None => format!("\"{}\"", table.sql_name),
+    };
+
     Regclass::new(<String as AsExpression<sql_types::Text>>::as_expression(
-        table.full_sql_name(),
+        table_name,
     ))
 }
 


Test patch:
diff --git a/diesel_cli/tests/print_schema.rs b/diesel_cli/tests/print_schema.rs
index 577d847511f8..a432ecd6d002 100644
--- a/diesel_cli/tests/print_schema.rs
+++ b/diesel_cli/tests/print_schema.rs
@@ -315,6 +315,23 @@ fn print_schema_several_keys_with_compound_key() {
     test_print_schema("print_schema_several_keys_with_compound_key", vec![])
 }
 
+// some mysql versions concert quoted table names to lowercase
+// anyway
+#[cfg(any(feature = "postgres", feature = "sqlite"))]
+#[test]
+fn print_schema_quoted_table_name() {
+    test_print_schema("print_schema_quoted_table_name", vec![])
+}
+
+#[cfg(feature = "postgres")]
+#[test]
+fn print_schema_quoted_schema_and_table_name() {
+    test_print_schema(
+        "print_schema_quoted_schema_and_table_name",
+        vec!["--schema", "CustomSchema"],
+    )
+}
+
 #[cfg(feature = "sqlite")]
 const BACKEND: &str = "sqlite";
 #[cfg(feature = "postgres")]
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/diesel.toml b/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/diesel.toml
new file mode 100644
index 000000000000..ad5457677877
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/diesel.toml
@@ -0,0 +1,3 @@
+[print_schema]
+file = "src/schema.rs"
+schema = "CustomSchema"
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/postgres/expected.snap b/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/postgres/expected.snap
new file mode 100644
index 000000000000..9022c22b4da9
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/postgres/expected.snap
@@ -0,0 +1,14 @@
+---
+source: diesel_cli/tests/print_schema.rs
+description: "Test: print_schema_quoted_schema_and_table_name"
+---
+// @generated automatically by Diesel CLI.
+
+pub mod CustomSchema {
+    diesel::table! {
+        CustomSchema.User (id) {
+            id -> Int4,
+        }
+    }
+}
+
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/postgres/schema.sql b/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/postgres/schema.sql
new file mode 100644
index 000000000000..90b508e2e51a
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_schema_and_table_name/postgres/schema.sql
@@ -0,0 +1,5 @@
+CREATE SCHEMA "CustomSchema";
+
+CREATE TABLE "CustomSchema"."User" (
+    id integer PRIMARY KEY NOT NULL
+);
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_table_name/diesel.toml b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/diesel.toml
new file mode 100644
index 000000000000..f57985adb185
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/diesel.toml
@@ -0,0 +1,2 @@
+[print_schema]
+file = "src/schema.rs"
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_table_name/postgres/expected.snap b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/postgres/expected.snap
new file mode 100644
index 000000000000..e2813cd9adb5
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/postgres/expected.snap
@@ -0,0 +1,12 @@
+---
+source: diesel_cli/tests/print_schema.rs
+description: "Test: print_schema_quoted_table_name"
+---
+// @generated automatically by Diesel CLI.
+
+diesel::table! {
+    User (id) {
+        id -> Int4,
+    }
+}
+
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_table_name/postgres/schema.sql b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/postgres/schema.sql
new file mode 100644
index 000000000000..5ab84f70c7ee
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/postgres/schema.sql
@@ -0,0 +1,3 @@
+CREATE TABLE "User" (
+    id integer PRIMARY KEY NOT NULL
+);
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_table_name/sqlite/expected.snap b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/sqlite/expected.snap
new file mode 100644
index 000000000000..2f59dc08d2fe
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/sqlite/expected.snap
@@ -0,0 +1,12 @@
+---
+source: diesel_cli/tests/print_schema.rs
+description: "Test: print_schema_quoted_table_name"
+---
+// @generated automatically by Diesel CLI.
+
+diesel::table! {
+    User (id) {
+        id -> Integer,
+    }
+}
+
diff --git a/diesel_cli/tests/print_schema/print_schema_quoted_table_name/sqlite/schema.sql b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/sqlite/schema.sql
new file mode 100644
index 000000000000..5ab84f70c7ee
--- /dev/null
+++ b/diesel_cli/tests/print_schema/print_schema_quoted_table_name/sqlite/schema.sql
@@ -0,0 +1,3 @@
+CREATE TABLE "User" (
+    id integer PRIMARY KEY NOT NULL
+);