Escaping keyword-like column names in Postgres

SqlPostgresql

Sql Problem Overview


If the column in Postgres' table has the name year, how should look INSERT query to set the value for that column?

E.g.: INSERT INTO table (id, name, year) VALUES ( ... ); gives an error near the year word.

Sql Solutions


Solution 1 - Sql

Simply enclose year in double quotes to stop it being interpreted as a keyword:

INSERT INTO table (id, name, "year") VALUES ( ... );

From the documentation:

> There is a second kind of identifier: the delimited identifier or > quoted identifier. It is formed by enclosing an arbitrary sequence of > characters in double-quotes ("). A delimited identifier is always an > identifier, never a key word. So "select" could be used to refer to a > column or table named "select", whereas an unquoted select would be > taken as a key word and would therefore provoke a parse error when > used where a table or column name is expected.

Solution 2 - Sql

If you are not providing quotes in any Fields/Columns, It will be lowercased by Postgres by default. And Postgres will skip checking keyword when it comes to the column name.

In your case, I don't think it's mandatory to add quotes when it comes to the columns. But if you are using keywords (registered by Postgres) as the name of Table, Schema, Function or Trigger etc, you must have to use either double quotes, or you can specify schema name with dot concatenation.

Let's Suppose, order is the keyword registered by Postgres. And in some scenarios, you must have to use this keyword as a table name.

At that time, Postgres will allow you to create a table with keywords. That is the beauty of Postgres.

To access the order table, Either you have to use a Double quote or you can you schema name before table name.

E.G.

select * from schema_name.order;
select * from "order";

Likewise, you can use this type of combination. Hope this will help you.

Solution 3 - Sql

To be on the safe side: Always quote identifiers! For this you have to build the insert statement with delimited identifiers.

SQL 2003 specifies that a delimited identifier should be quoted with double quotes " and if a double quote occurs in the identifier, the double quote must be duplicated. See the BNF:

https://ronsavage.github.io/SQL/sql-2003-2.bnf.html#delimited%20identifier

This is Java code to quote the identifier:

static String delimited_identifier (String identifier)
{
  return "\"" + identifier.replaceAll ("\"", "\"\"") + "\"";
}

And this is the code to build the insert:

static String build_insert (String table, String[] columns)
{
  StringBuilder sql = new StringBuilder ();
  StringBuilder values = new StringBuilder ();

  sql.append ("INSERT INTO ");
  sql.append (delimited_identifier (table));
  sql.append (" (");
  int c = 0;
  if (columns.length > 0) {
    sql.append (delimited_identifier (columns[c]));
    values.append ("?");
  }
  for (++c; c < columns.length; c++) {
    sql.append (", ");
    sql.append (delimited_identifier (columns[c]));
    values.append (", ?");
  }
  sql.append (") VALUES (");
  sql.append (values.toString ());
  sql.append (")");

  return sql.toString ();
}

Example:

String sql = build_insert ("Person", new String[]{"First name", "Last name"});

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionshybovychaView Question on Stackoverflow
Solution 1 - SqlNPEView Answer on Stackoverflow
Solution 2 - SqlMayurView Answer on Stackoverflow
Solution 3 - SqlcevingView Answer on Stackoverflow