Skip to content

Commit

Permalink
Add article about case sensitivity
Browse files Browse the repository at this point in the history
  • Loading branch information
yen223 committed Nov 3, 2024
1 parent f339de1 commit d903b41
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions articles/avoid-capital-letters-in-postgres-names.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: "Avoid capital letters in Postgres names"
slug: "avoid-capital-letters-in-postgres-names"
date: "2024-11-03"
published: true
tags:
- sql
- database
description: "Because Postgres have counterintuitive rules around case."
---

In Postgres, if you create a table with a camelCase name, you will not be able to reference the table without quoting the name.

```sql
CREATE TABLE "camelCaseTable" (
id SERIAL PRIMARY KEY,
name TEXT
);

SELECT * FROM camelCaseTable; -- ERROR: relation "camelcasetable" does not exist
SELECT * FROM "camelCaseTable"; -- WORKS
```

In Postgres, identifiers (i.e. names of tables, columns and other database objects) are case-sensitive. A table named `camelCaseTable` is different from a table named `camelcasetable`.

According to the docs:

> Quoting an identifier also makes it case-sensitive, whereas unquoted names are always folded to lower case. For example, the identifiers FOO, foo, and "foo" are considered the same by PostgreSQL, but "Foo" and "FOO" are different from these three and each other. (The folding of unquoted names to lower case in PostgreSQL is incompatible with the SQL standard, which says that unquoted names should be folded to upper case. Thus, foo should be equivalent to "FOO" not "foo" according to the standard. If you want to write portable applications you are advised to always quote a particular name or never quote it.)
>
> Source: [Postgres docs](https://www.postgresql.org/docs/current/sql-syntax-lexical.html#:~:text=Quoting%20an%20identifier,never%20quote%20it.%29)

An unquoted identifier in any SQL statement is "folded" to a lowercased version of itself. So these two queries are effectively the same:

```sql
-- Both will select from the table "camelcasetable".
SELECT * FROM camelCaseTable;
SELECT * FROM camelcasetable;
```

A quoted identifier always preserves the case. So these two queries are different:

```sql
-- These are different!
SELECT * FROM "camelCaseTable";
SELECT * FROM "camelcasetable";
```

That's why the original example fails. The created table has name `camelCaseTable` with the capital letters, but the select query was looking for a table named `camelcasetable`, all lowercase.

Note that this applies to all identifiers in Postgres, so all of this applies to column names, index names and generally names of database objects.

This is why I recommend avoiding capital letters in Postgres table names. Avoiding capital letters in your naming convention will remove an entire class of complexity stemming from case-sensitivity rules.

0 comments on commit d903b41

Please sign in to comment.