Does case matter at all when you define or call a function in PostgreSQL?
Function names are identifiers (like table names, field names), the same rules about case sensitivy apply to all.
In short, identifiers are case insensitive, unless quoted.
More precisely, an unquoted identifier is internally converted to lowercase and then a case sentitive match is attempted.
This can make your life miserable (i.e hidden bugs, hours wasted), typically if you used quoted identifiers when defining the table or function.
That's why you should always define your own naming convention and stick to it.
General advice: use always lowercase for identifiers, and be happy.
db=# select now();
now
-------------------------------
2011-06-10 16:33:06.588401-03
(1 row)
db=# select Now();
now
-------------------------------
2011-06-10 16:33:08.066818-03
(1 row)
db=# select "now"();
now
-------------------------------
2011-06-10 16:33:14.543381-03
(1 row)
db=# select "Now"();
ERROR: function Now() does not exist
LINE 1: select "Now"();
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
I suppose you can get lots of varying answers to this question. Technically, function names in PostgreSQL are case sensitive. But when you address a function through SQL, identifier syntax rules apply, namely that unquoted identifiers are folded to lower case. This can give the illusion of case insensitive function names, but it's only the idiosyncrasy of the SQL language. Contrast this, for example, with names of procedural languages, which are case insensitive even if you double quote the identifiers.
Identifier and key word names in PostgreSQL are case insensitive. Function names are identifiers.
Related
How can I update my Postgresql database to be case insensitive ?
I already have like some tables and some data, and currently they are case sensitive but I would like to update all of them to be case insensitive.
You cannot get your database to be case insensitive, but from v12 on you can create a case insensitive ICU collation and use that with column definitions:
CREATE COLLATION english_ci (
PROVIDER = 'icu',
LOCALE = 'en-US#colStrength=secondary',
DETERMINISTIC = FALSE
);
That could be used like this:
CREATE TABLE testtab (ci_col text COLLATE english_ci);
Comparisons are case insensitive:
SELECT 'Hello' = 'hello' COLLATE english_ci;
?column?
══════════
t
(1 row)
There's a question about this related to emails that has useful insight: PostgreSQL: Case insensitive string comparison
Basically it seems there are a few approaches. You Can
Use lower() in indexes and make sure to use it on every query clause including this column.
Convert to citext (available in postgres 9) which internally compares by using lower() while retaining normal behavior of text otherwise.
Worst of all, probably, you could just force data to lower case on insert with a database trigger.
I am making an application that needs to construct Postgresql queries that will execute successfully in scenarios when table names are reserved keywords etc.
In Sql Server syntax this is achieved by wrapping everything in square brackets [] i.e. SELECT * FROM [database].[schema].[table_name].
I thought the equivalent in Postgresql was the use of double quotes "" i.e. SELECT * FROM "database"."schema"."table_name".
However, when I try this in Postgresql I get the error
Relation X doesn't exist
This works:
SELECT * FROM "postgres"."schema_a".Academic_Attainment
But this doesn't:
SELECT * FROM "postgres"."schema_a"."Academic_Attainment"
Related to: Escaping keyword-like column names in Postgres
Any suggestions?
As documented in the manual unquoted identifiers are folded to lowercase.
A quoted identifier is also case sensitive, so "Foo" is a different name than "foo".
So the name Academic_Attainment is the same as academic_attainment. If you really insist on using those dreaded double quotes, then you need to use a lower case identifier:
SELECT *
FROM "schema_a"."academic_attainment"
In general it's strongly recommended to not use quoted identifiers at all. As a rule of thumb: never use double quotes and you are fine.
If you are constructing dynamic SQL, use the format() function to do that together with the %I placeholder. It will take care of quoting if necessary (and only then), e.g.
format('select * from %I.%I', 'public', 'some_table') yields select * from public.some_table but format('select * from %I.%I', 'public', 'group') yields select * from public."group"
Unrelated to your question: Postgres doesn't support cross-database queries, so you should not get into the habit including the database name into your fully qualified names. The syntax you are using only works because you are connected to the database postgres. So I would recommend to stop using the database name in any table reference.
I wonder if someone could have an idea what is going wrong with this simple query on a hstore column in PostgreSQL 9.2
The queries are runned in pgAdmin
select attributeValue->"CODE_MUN" from shapefile_feature
returns: « attributevalue » column does not exists
when doing:
select * from shapefile_feature;
all the columns are returned including attributeValue, the hstore column
what is the problem?
PostgreSQL distinguish between "identifiers" and 'literal'. Identifiers are schema, table, column's, .. names, literals are others. A attribute in hstore are not SQL identifiers. So you have to pass their names as literals. Operator "->" is only shortcut for function "fetchval(hstore, text)" with possibility be indexed.
select attributeValue->'CODE_MUN' from shapefile_feature
is internally transformed to (don't do this transformation by self!)
select fetchval(attributeValue, 'CODE_MUN') from shapefile_feature
on buggy example in transformed form, you can better understand to error message:
select fetchval(attributeValue, "CODE_MUN") from shapefile_feature
PostgreSQL tries to find column "CODE_MUN" in shapefile_feature, bacause used double quotes means identifiers (in case sensitive notation).
I am using Ubuntu and PostgreSql 8.4.9.
Now, for any table in my database, if I do select table_name.name from table_name, it shows a result of concatenated columns for each row, although I don't have any name column in the table. For the tables which have name column, no issue. Any idea why?
My results are like this:
select taggings.name from taggings limit 3;
---------------------------------------------------------------
(1,4,84,,,PlantCategory,soil_pref_tags,"2010-03-18 00:37:55")
(2,5,84,,,PlantCategory,soil_pref_tags,"2010-03-18 00:37:55")
(3,6,84,,,PlantCategory,soil_pref_tags,"2010-03-18 00:37:55")
(3 rows)
select name from taggings limit 3;
ERROR: column "name" does not exist
LINE 1: select name from taggings limit 3;
This is a known confusing "feature" with a bit of history. Specifically, you could refer to tuples from the table as a whole with the table name, and then appending .name would invoke the name function on them (i.e. it would be interpreted as select name(t) from t).
At some point in the PostgreSQL 9 development, Istr this was cleaned up a bit. You can still do select t from t explicitly to get the rows-as-tuples effect, but you can't apply a function in the same way. So on PostgreSQL 8.4.9, this:
create table t(id serial primary key, value text not null);
insert into t(value) values('foo');
select t.name from t;
produces the bizarre:
name
---------
(1,foo)
(1 row)
but on 9.1.1 produces:
ERROR: column t.name does not exist
LINE 1: select t.name from t;
^
as you would expect.
So, to specifically answer your question: name is a standard type in PostgreSQL (used in the catalogue for table names etc) and also some standard functions to convert things to the name type. It's not actually reserved, just the objects that exist called that, plus some historical strange syntax, made things confusing; and this has been fixed by the developers in recent versions.
According to the PostgreSQL documentation, name is a "non-reserved" keyword in PostgreSQL, SQL:2003, SQL:1999, or SQL-92.
SQL distinguishes between reserved and non-reserved key words. According to the standard, reserved key words are the only real key words; they are never allowed as identifiers. Non-reserved key words only have a special meaning in particular contexts and can be used as identifiers in other contexts. Most non-reserved key words are actually the names of built-in tables and functions specified by SQL. The concept of non-reserved key words essentially only exists to declare that some predefined meaning is attached to a word in some contexts.
The suggested fix when using keywords is:
As a general rule, if you get spurious parser errors for commands that contain any of the listed key words as an identifier you should try to quote the identifier to see if the problem goes away.
Simple question, is there any way to omit the double quote in PostgreSQL?
Here is an example, giving select * from A;, I will retrieve ERROR: relation "a" does not exist, and I would have to give select * from "A"; to get the real result.
Is there any way not to do the second and instead do the first on PostgreSQL?
Your problem with this query started when you created your table. When you create your table, don't use quotes.
Use this:
CREATE TABLE a ( ... );
Not this:
CREATE TABLE "A" ( ... );
The latter will make it so that you always have to quote it later. The former makes it a normal name and you can use SELECT * FROM a; or SELECT * FROM A;
If you can't just recreate your table, use the ALTER TABLE syntax:
ALTER TABLE "A" RENAME TO a;
double quotes are required if you include capital letters in your table name in postgres
to avoid the requirements name your table "a"
Postgresql has some particular behaviour in regard to quoting and case sentivity: it folds every non-quoted identifier to lower case (also at creation time) and then works case-sensitively.
Double quotes in identifiers are only needed when the identifier (table name, column name, etc) was defined (at schema creation time) with uppercase letters (some or all) and between double quotes.
In that case (which I advice against), when you use that identifier, you must type it in the same way: case sensitively (type upper/lower case letter exactly as defined) and between double quotes.
In other cases, you can use non-quoted identifiers and work always case-insensitively.
Don't use upper case letter in your table name or it's column name, if you are using such thing then the postgres will required double quote for accessing it.
Please see the detailed description of what is happening here.
The PostgreSQL server table names are case-sensitive, but forced to be lower-case by default: when you type CREATE TABLE AAA, it will become CREATE TABLE aaa before the query execution.
Double-quoted names keep their case as it was, so after CREATE TABLE "AaA" you get the table AaA and have to write it double-quoted again and again.
Have no idea why did they do so :)