Skip to content
\n
\n

Identifier Resolution and Case Sensitivity

\n

Unquoted vs. Quoted Identifiers
\nWhen you write a table name without quotes (e.g., mytable), PostgreSQL automatically converts it to lowercase. That means:

\n

A table created as

\n

CREATE TABLE mytable (id SERIAL PRIMARY KEY);

\n

is stored as mytable, and any reference like SELECT * FROM MYTABLE; is interpreted as mytable.

\n

If you create a table with quotes and mixed case, for example:

\n

CREATE TABLE \"MyTable\" (id SERIAL PRIMARY KEY);

\n

PostgreSQL treats \"MyTable\" as case-sensitive. Every query must then refer to it exactly as \"MyTable\" with the same letter casing.

\n

Schema Resolution and the Search Path

\n

Schemas in PostgreSQL

\n

Tables are organized into schemas. By default, if you don’t specify a schema, tables go into the public schema.

\n

Search Path

\n

When you issue an unqualified table reference (e.g., SELECT * FROM mytable;), PostgreSQL looks for the table in the schemas listed in the search_path.

\n

To see the current search path, run:

\n

SHOW search_path;

\n

If your table is in a different schema (say, sales), either qualify the table name:

\n

SELECT * FROM sales.mytable;

\n

or adjust the search path:

\n

SET search_path TO sales, public;

\n

To verify if your table exists in another schema, run:

\n

SELECT table_schema, table_name
\nFROM information_schema.tables;

\n

Directly Check the System Catalog

\n

You can search for your table in PostgreSQL’s catalog. Replace your_table with the exact table name (remember the case!):

\n

SELECT *
\nFROM pg_catalog.pg_tables
\nWHERE tablename = 'your_table';

\n

Query with Case Sensitivity

\n

If your table was created using quotes (e.g., \"MyTable\"), make sure you reference it with the correct case:

\n

SELECT * FROM \"MyTable\";

\n

Common Pitfalls and Their Resolutions

\n

Case Mismatch:
\nIf your table was created with quotes and mixed case, unquoted references won’t work because PostgreSQL folds unquoted names to lowercase. Always use double quotes with the exact case if needed.

\n

Wrong Schema:
\nThe table might exist in a schema that isn’t in your current search path. Use a fully qualified name (schema.table) or update your search path.

\n

Incorrect Database Connection:
\nVerify with current_database() that you’re querying the intended database.

\n

Insufficient Permissions:
\nAlthough not as common with “relation does not exist” errors, ensure your user has access to the table.

","upvoteCount":1,"url":"https://github.com/sqlpage/SQLPage/discussions/885#discussioncomment-12813766"}}}

Relation "xyz" does not exist #885

Answered by lovasoa
chambrickShS asked this question in Q&A
Discussion options

You must be logged in to vote

👋 Hello and welcome to SQLPage!

The “relation does not exist” error means that you're successfully connected to postgres, but are trying to query a table that does not exist.

With SQLite, naming isn’t an issue, but in Postgres unquoted identifiers are automatically lower-cased. If your table was created with upper-case letters or special characters, you need to quote them.

Also, verify that the connection URL is actually targeting the database and schema where your table exists (typically the “public” schema).

Adjusting your table naming or explicitly quoting identifiers should resolve the error.

To spot the difference, you can run the following queries, one at a time, from dbeaver then f…

Replies: 1 comment 2 replies

Comment options

You must be logged in to vote
2 replies
@chambrickShS
Comment options

@lovasoa
Comment options

Answer selected by chambrickShS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants