Cannot create a database table named 'user' in PostgreSQL - postgresql

It seems PostgreSQL does not allow to create a database table named 'user'. But MySQL will allow to create such a table.
Is that because it is a key word? But Hibernate cannot identify any issue (even if we set the PostgreSQLDialect).

user is a reserved word and it's usually not a good idea use reserved words for identifiers (tables, columns).
If you insist on doing that you have to put the table name in double quotes:
create table "user" (...);
But then you always need to use double quotes when referencing the table. Additionally the table name is then case-sensitive. "user" is a different table name than "User".
If you want to save yourself a lot of trouble use a different name. users, user_account, ...
More details on quoted identifiers can be found in the manual: http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS

It is possible to specify tablename with JPA with next syntax:
#Table(name="\"user\"")

We had this same issue time ago, and we just changed the table name from user to app_user. Due to the use of Hibernate/JPA. We thought it would be easier this way.
Hope this little fix will help someone else.

You can create a table user in a schema other than public.
The example:
CREATE SCHEMA my_schema;
CREATE TABLE my_schema.user(...);

Trailing underscore
The SQL standard explicitly promises to never use a trailing underscore in any keyword or reserved word.
So, to avoid conflicts with any of the over a thousand keywords and reserved words used by various database engines, I name all my database identifiers with a trailing underscore. (Yes, really, over a thousand keywords reserved — I counted them.)
Change this:
CREATE TABLE user ( … ) ;
… to this:
CREATE TABLE user_ ( … ) ;
I do this as a habit for all database names: schemas, tables, columns, indexes, etc.
As an extra benefit, this practice makes quite clear in documentation, email, and such when referring to a programming language variable named user versus the database column user_. Anything with a trailing underscore is obviously from the database side.

Related

Changing schema name within functions

I have schema1 in database1. I want to move all the functions of schema1 to schema2 which is present in database2. I have restored backup file of database1 into database2. And changed the schema name. The schema name for function call automatically got changed. But within function definition the schema name is not changed. for ex:
CREATE OR REPLACE FUNCTION schema2.execute(..)
BEGIN
select schema1."VALIDATE_SESSION"(....)
end
How can I change "schema1" to "schema2" automatically?
I have tried to store current schema name in variable and append it to table. But calling current_schema() returns "public". How to get current schema created by user? Because every time I need to change the schema name while generating script.
The essential detail that is missing in your dummy function are the single quotes (or dollar-quotes, all the same) around the function body. Meaning, function bodies are saved as strings. See:
What are '$$' used for in PL/pgSQL
To contrast, consider a reference to a table (or more verbosely: schema.table(column)) in a FK constraint. Object names are resolved to the internal OID of the table (and a column number) at creation time. "Early binding". When names (including schema names) are changed later, that has no effect on the FK at all. Feels like involved names are changed dynamically. But really, actual names just don't matter after the object has been created. So you can rename schemas all day without side effect for the FK.
Names in a function body are stored as strings and interpreted at call time. "Late binding". Those names are not changed dynamically.
Meaning, you'll have to actually edit all function bodies including a hard-coded schema name. A possible alternative is to rely on the search_path instead and not use schema names in function bodies to begin with. There are various. See:
How does the search_path influence identifier resolution and the "current schema"
But that's not always acceptable.
You could hack the dump. Or use sting manipulation inside Postgres to update affected function bodies. Find affected functions with a meta-query like:
SELECT *
FROM pg_catalog.pg_proc
WHERE prosrc ~ '\mschema1\M'; -- not bullet-proof!
Either way, be wary of false matches if the schema name can be part of other strings or pop up as column name etc. And dynamic SQL can concatenate strings in arbitrary ways. If you have such evil trickery in your functions, you need to deal with it appropriately.

Postgres "Like" Keyword

I am trying to create a temporary table in postgres by copying the column names and types from an existing table.
CREATE TEMPORARY TABLE temporary_table LIKE grades;
Typing the query into Postgre, it tells me about an error in LIKE. Is "Like" keyword not usable in Postgre or am I doing something wrong?
You need to wrap the like statement in parentheses:
CREATE TEMPORARY TABLE temporary_table (LIKE grades);
If you want defaults or indexes included as well, you need to add that explicitly
CREATE TEMPORARY TABLE temporary_table
(LIKE grades INCLUDING INDEXES INCLUDING DEFAULTS);

PostgreSQL renaming table sequences and primary key

Is it necessary or important to rename table sequences and primary keys when we rename a table in PostgreSQL? Does it affect something?
Technically your database will keep working as always without the rename so I would say it depends. If your primary key has a generic name like id obviously it is still valid regardless of the new table name. If the name is in the form old_table_name_id or something like that then you have semantic inconsistency. In larger projects this can be confusing for humans. Good names are important just like they are in code so I would rename in this case. Same goes for sequences.
No, unless you want to keep the names in sync to avoid confusing people.
The identity of an object is its Oid.

table naming and organizing of tables in postgresql

I'm trying to organize my PosgtresSql tables according to the application components they correspond to. For example, tables related to 'story' such as 'story_contents', 'story_comments', 'story_layout': would it best to keep a simple '' naming convention as presented? Would there be any drawback to using a '.' instead of ''? ... or is there a best practice that I'm completely overlooking?
Short answer:
Sure, if you place the entire database/table/column name reference in quotes
Long answer:
In Postgres, and most other databases, the dot is used to separate database name from table name, and table name from column name. For example, if you had a database called MyDB, with a table called MyTable and column in that table MyCol, then you could write the following SELECT statement:
SELECT MyDB.MyTable.MyCol
FROM MyDB.MyTable
However, if your database, table, and/or column names themselves had dots in them, then doing a SELECT might not work. In this case, I believe you can escape the fully qualified name (or portion) with quotes. So, if you had a column called MyCol.Col1, you could do the following:
SELECT "MyDB.MyTable.MyCol.Col1"
FROM MyDB.MyTable
The comment by #vector seems to be pointing in the right direction (no pun intended), and you should lean towards using underscores or some other character to separate out your schema names, rather than using a dot.

Creating reference with tables

I have two tables that already have data in them and i would like to create reference via postgressql OR SQL shell. The reference should be like this:
[IMG]http://i.imgur.com/SMUEo4r.png[/IMG]
Can anyone tell me how to do that?
alter table statusi
add constraint fk_darbinieki_statusi
foreign key (id_darbinieks) references darbinieki (id_darbinieks);
Note that I used unquoted identifiers which are case insensitive.
Given your screenshot it might be that you created quoted identifiers using double quotes which are case sensitive. "ID_statusi" is a different name than ID_statusi. So maybe you need to use double quotes when running the above statement. In general, using double quotes for identifiers is not such a good idea. It creates more trouble than it's worth.
More details in the manual:
defining foreign keys:http://www.postgresql.org/docs/current/static/ddl-constraints.html#DDL-CONSTRAINTS-FK
Rules for identifiers: http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
ALTER TABLE: http://www.postgresql.org/docs/current/static/sql-altertable.html