dbal: Postgres: public should not be considered a "application schema" and should be ignored the same as other system schema from `getSchemaNames`
Bug Report
For now 10 years public
has been returned by getSchemaNames
generating a lot of bug and weird behaviour in higher level libraries relying on it.
Q | A |
---|---|
Version | 3.x |
Summary
For now 10 years since commit https://github.com/doctrine/dbal/commit/b89490a557584b61d575aaa67f8b386d833d5a0f (before that it was not working at all )
public
is returned by PostgreSQLSchemaManager::getSchemaNames()
Current behaviour
How to reproduce
(a reproducer is soon coming)
- connect to any postgresql (a vanilla postgres docker is fine)
- call PostgreSQLSchemaManager::getSchemaNames -> public is returned among other user-defined schema
Expected behaviour
all application schema are returned , but not public
(as well as other postgres-defined schema are also not returned
More context
This bug is at least the root cause of these issues
- https://github.com/doctrine/migrations/issues/441
- https://github.com/doctrine/migrations/issues/1196#issuecomment-1029706768
- https://github.com/doctrine/dbal/issues/1110
- https://github.com/doctrine/dbal/issues/1188#issuecomment-231751027
- https://github.com/doctrine/orm/issues/4777
- https://github.com/symfony/symfony/issues/44952
the more visible issue of it is with doctrine migration:
- all migrations contains a
down
migration trying toCREATE SCHEMA public
that EVERYBODY deletes or workaround ( đŻ if you have done that too ) because it fails miserably (as it already exists) - to avoid dropping it , we donât drop schemas at all cf https://github.com/doctrine/dbal/pull/5604/files , so if automated generated migrations are not bijectives because
DROP SCHEMA
will never be generated.
Why public
should be considered a âsystem schemaâ
- public is not created by the user
- everybody assume that it is present
- even postgres assumes it is present
- it has a behaviour that no user-defined schema has (i.e omitting the name of the schema default to âpublicâ , i.e when you do
CREATE TABLE foobar
youâre actually doingCREATE TABLE public.foobar
- if a ill-advised user drop it, a lot of libraries get broken ( doctrine migration by default create is own internal table in the public namespace , so as this SQL runs BEFORE the first migration, you canât even create back
public
in the first migration as it will fail before) - weak argument: after 10 years of managing postgresql I never ever seen people dropping and even less (re)creating the public schema, the only case I could hypothetically see for it is a extremly ordered DBA that have severa applications on the same instance , and want each of them in its own schema to ease maintenance (but in that case itâs the âinfrastrctureâ responsability to drop it once and for all, not one of the applications )
@morozov I understand the issue is âscaryâ because this library is a high profile one and after a time even bugs become part of the API , so I understand we may want to be careful on that one, so maybe we can find a deprecation strategy and changing this behaviour only on a minor/major release (at least not just a bug fix one)
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 1
- Comments: 23 (7 by maintainers)
Indeed, Iâve taken a look, and although it could be fixed in the ORM by tweaking
SchemaTool::getSchemaFromMetadata()
, that would make ORM schema creation attempt to create thepublic
PG schema.I see that DBAL has a
schemaAssetsFilter
configuration node, which I could not find documentation on but seems to be about making the DBAL ignore assets it should not manage. This leads me to formulating the following problem:While it is possible to filter out assets in a schema, itâs not possible to filter out schemas in a database.
A solution could be to add another configuration node just for this, and let the user configure it. That way we donât need to make any assumptions about what the user thinks about
public
. Assumptions should be made in Symfony recipes. That assumption should be made here, in the form of a commented out configuration node.public
, so if you drop publicselect * from articles
will breakBy default such tables (and other objects) are automatically put into a schema named âpublicâ. Every new database contains such a schema.
https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PUBLIC so it read as ⌠well âit is present in every new databaseâ , i donât know whereâs the subjective interpertration you canIâm really sorry but what kind of proof more than that do you need , if I rephrase it as "major projects, including the database itself use it as a default value because except if youâre doing very specific stuff, it will be there " would a more objective statement ? if not how do you describe my points ?
also whatâs really frustrating is that these points are from my above comments, I really took the time to gather them, and you decide to discard them
i feel a bit disappointed , the stated issues are clear not a opinion, the âopinionâ is a consequence of these issues, not the other way around,
facts:
when you tried to consider public as a normal schema while adding the possibly for dbal to report SQL to drop schema , you had issues
as a consequence of that i see that the way to solve this is to consider public as special schema
Iâm not some kind of militan that think public should be considered special out of the blue and here find a way to spread my propaganda , iâm just a pragmatic people who try to find solution to problem
so please first discard the facts before focusing on the proposed solution
thanks for pointing that out, I was looking if it was overridable and it was right under my nose.
However my other point still stands and this one is slighltly amended , as in the case of a DBA requesting the
search_path
to be overrided to avoid accidental use of publc , it means even more that public should not be touched at all by the application layer