when table name include a DOT , JPA throw "INSERT command denied to user for table 'XXX'" - jpa

I have a strange issue with JPA. I have renamed a table in my database from "Users" to "App.Users". And put this annotation to my entity class: #Table(name="App.Users") then I got this error:
INSERT command denied to user 'XXXXX'#'XXXXX' for table 'Users'
I am using MariaDB.

Please read the chapter Identifier names of MariaDB documentation.
Identifiers with characters which are not ANSI characters in the range [0-9,a-z,A-Z$_] and which are not unicode characters >= 0x0080FF have to be quoted in backticks.
The decimal point in unquoted identifiers additionally has a special meaning: In your example it means schema/database "App" and table "Users". Since the user has no privileges on database App (event if it doesn't exist) a privilege error occurred.

Related

Should the table name "user" be used in a Symfony project?

I know this sounds like an "opinion" question, but I don't think it is.
Normally, I would consider not using "user" as a table name as it is a reserved word, and I would rather not bother having to deal with it when I write native SQL queries.
But I am not writing native SQL queries, but am having Symfony and the Doctrine ORM perform all the queries. And when I execute php bin/console make:user, Symfony prompts me to select the class name User which results with user as the table name. Furthermore, most of the tutorials I have read also use the name user. If using the name user is what is most common for other developers, I would rather stay consistent.
Most of the time, I don't have any issues, but every now and then, Doctrine crashes because it is querying the Postgres internal user table and not public.user. As a workaround, I tried adding * #ORM\Table(schema="public") to the User entity, but then when making migrations, it tries to duplicate the record resulting in errors. Maybe Symfony/Doctrine needs to be configured somewhere as using the public schema?
Thanks
Since my question was "Should the table name “user” be used in a Symfony project?", the following doesn't answer the question, but I am still posting it should it be helpful for others. Perhaps I will change the title to "How to use the table name “user” in a Doctrine project?", but not sure whether doing so is kosher.
I've since discovered other's experiencing issues resulting from this topic:
https://github.com/doctrine/dbal/issues/1222
https://github.com/symfony/maker-bundle/pull/545
Also found the following at doctrine-adding-mapping:
Be careful not to use reserved SQL keywords as your table or column
names (e.g. GROUP or USER). See Doctrine’s Reserved SQL keywords
documentation for details on how to escape these. Or, change the table
name with #ORM\Table(name="groups") above the class or configure the
column name with the name="group_name" option.
Which directed me to quoting-reserved-words which directed me to escape the name using ticks.
* #ORM\Table(name="`user`")
There is no table user in PostgreSQL.
Tutorials that use user as a table name are not trustworthy. However, if you consistently use double quotes, there should be no problem. Since you claim to have problems with native queries, you might have forgotten that occasionally.
One possible source of confusion is that there is a function named user in PostgreSQL. So if you use user in a context where a function is possible, you'll get a function call. If you use it with schema qualification, you will get an error that there is no such object. Otherwise, you will get a syntax error:
test=> SELECT user;
user
---------
laurenz
(1 row)
test=> SELECT * FROM user;
user
---------
laurenz
(1 row)
test=> TABLE user;
ERROR: syntax error at or near "user"
LINE 1: TABLE user;
^
test=> SELECT * FROM public.user;
ERROR: relation "public.user" does not exist
LINE 1: SELECT * FROM public.user;
^

Creating and accessing a schema beginning with a numeric value in Postgresql

I generate a 10-character alphanumeric random string as a schema name for each new tenant in my DB.
In this one instance, it generated "5ku2mug7m8" as the string. The schema was created correctly (in pic) but when accessing the schema, an error of
"ERROR: syntax error at or near "5"
LINE 1: SELECT * FROM 5ku2mug7m8.tablename"
which I gather is due to the leading numeric. I tried wrapping the schema in double-quotes ("") but postgres doesn't accept that.
My question is: if I cannot access a schema with a leading numeric, why does postgres allow the creation of it in the first place? Now I have sitting in the DB a schema that can't be accessed -- unless it can be and I'm just missing it?
EDIT: From documentation,
SQL identifiers and key words must begin with a letter (a-z, but also
letters with diacritical marks and non-Latin letters) or an underscore
(_). Subsequent characters in an identifier or key word can be
letters, underscores, digits (0-9), or dollar signs ($). Note that
dollar signs are not allowed in identifiers according to the letter of
the SQL standard, so their use might render applications less
portable...
But why allow creation of the schema without any errors in the first place? Curious.
You probably created the schema with pgAdmin, and that tool automatically added the double quotes for you.
You can certainly delete the schema with
DROP SCHEMA "5ku2mug7m8";
unless you have nasty things like leading or trailing blanks in the schema name.
You can find out the real schema name with:
SELECT quote_ident(nspname)
FROM pg_namespace
WHERE nspname LIKE '%5%';
Your experience and your research of the documentation is valuable. You have seen why it is a bad idea to pick object or column names (“identifiers”) that are valid SQL identifiers and don't need double quotes.
You can create a schema whose name starts with a digit if the schema name is using double quotes.
Demo with psql:
# select version();
version
--------------------------------------------------------------------------------
-------------------------
PostgreSQL 12.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (R
ed Hat 4.8.5-39), 64-bit
# create schema "5ku";
CREATE SCHEMA
# create table "5ku".t(x int);
CREATE TABLE
# select * from "5ku".t;
x
---
(0 rows)

How to rename a PostgreSQL table by prefixing an underscore?

I have a database which relies on a PostgreSQL system and I am maintaining it so I want to change tables and overall scheme. For this I thought of renaming the older tables so they have an underscore as a prefix. But this is not working:
DROP TABLE IF EXISTS _my_table; -- table does not exists, this does nothing
ALTER TABLE my_table
RENAME TO _my_table;
The result of the query is the following:
NOTICE: table "_my_table" does not exist, skipping ERROR:
type "_my_table" already exists
********** Error **********
ERROR: type "_my_table" already exists SQL state: 42710
The '_my_table' table is a fake name, but this error is reproduced by actually creating a '_my_table' table and running the same script above.
I am using pgAdmin III to access the database tables and making use of it's 'rename' operation results in the same error.
The postgresql documentation for the alter table method does not tell me explicitly about this particular problem: http://www.postgresql.org/docs/9.3/static/sql-altertable.html
Do I really need to use a prefix like 'backup' instead of '_' ? Or would it be possible to rename it, my only interest is to maintain the information in the table whilst having the minimal changes to the table name.
You cannot simply put an underscore in front of the existing table name because every table has an associated type that is... a leading underscore before the table name. You can verify this in the pg_catalog.pg_type table. Having a table name start with an underscore is not the problem, but the internal procedure is that a new table is created physically from the old table and only when the old table is no longer in use by other processes will the old table, and its associated type, be deleted. Hence the error referencing the type (and not the relation).
So if you really want to keep the old name with an underscore, you should first ALTER TABLE to some temp name and then ALTER TABLE to the underscore + original name. Or simply use another prefix...
ERROR: type "_my_table" already exists
Both tables and types are stored in the internal table pg_class. A unique name is required, that's why you get this error message.

pgAdmin error - relation "[name of function/Views/Trigger Functions]" does not exist

I'm just new to pgAdmin, so I don't really know what causes these errors:
ERROR: relation "ongoingprojects" does not exist
LINE 1: SELECT * FROM ongoingProjects;
^
********** Error **********
ERROR: relation "ongoingprojects" does not exist
SQL state: 42P01
Character: 15
Even if the function/view exists in the schema. Why does it give that error? And what should I do to fix it?
Pay careful attention to the error message:
ERROR: relation "ongoingprojects" does not exist
Note that it is complaining about ongoingprojects when your SQL talks about ongoingProjects. You probably created the table with something like:
create table "ongoingProjects" ( ...
PostgreSQL folds all identifiers (table names, column names, ...) to lower case unless they are double quoted. Once you've created the table as "ongoingProjects", you'll have to double quote the name everywhere and exactly match that case:
select * from "ongoingProjects";
The usual practice with PostgreSQL is to create tables with unquoted names in lower case with word separated using underscores:
create table ongoing_projects ( ...
so that you don't have worry about quoting.
Here is the link to the relevant part of the manual
For me the issue was having a schema named differently than the database.
Two solutions:
1) Modify schema name to match db name
or
2) Prepend table in query with schema name, eg: SELECT * FROM my_schema.ongoingProjects;

Firebird and Table,field name lowercase

I have converted a database from MySQL to Firebird, all tables name and field name are in lowercase, when I query the database, it gives me an error of table not found, because Firebird automatically converted the name of table in the query in UPPERCASE letters, but my table name in database is lowercase.
To query the database, I'm required to enclose the name of the table or the name of the field in double quotes, for example:
SELECT "field1","field2" FROM "table"
Is there a setting in Firebird to allow to query database with table/field name in lowercase letter without quoting it?
No. BTW, I suggest you to always create DB objects in uppercase (and without double quotes) in Firebird. This simplifies a lot, since you can access them writing in any case (even mixed case).