2003-06-27 16:45:32 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* alter.c
|
|
|
|
* Drivers for generic alter commands
|
|
|
|
*
|
2020-01-01 18:21:45 +01:00
|
|
|
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
2003-06-27 16:45:32 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/backend/commands/alter.c
|
2003-06-27 16:45:32 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
2012-08-30 22:15:44 +02:00
|
|
|
#include "access/htup_details.h"
|
2019-01-21 19:18:20 +01:00
|
|
|
#include "access/relation.h"
|
2012-10-03 23:02:38 +02:00
|
|
|
#include "access/sysattr.h"
|
2019-01-21 19:18:20 +01:00
|
|
|
#include "access/table.h"
|
2010-11-26 23:27:23 +01:00
|
|
|
#include "catalog/dependency.h"
|
|
|
|
#include "catalog/indexing.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "catalog/namespace.h"
|
2013-03-18 03:55:14 +01:00
|
|
|
#include "catalog/objectaccess.h"
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
#include "catalog/pg_collation.h"
|
|
|
|
#include "catalog/pg_conversion.h"
|
2013-01-21 16:06:41 +01:00
|
|
|
#include "catalog/pg_event_trigger.h"
|
|
|
|
#include "catalog/pg_foreign_data_wrapper.h"
|
|
|
|
#include "catalog/pg_foreign_server.h"
|
|
|
|
#include "catalog/pg_language.h"
|
2009-12-11 04:34:57 +01:00
|
|
|
#include "catalog/pg_largeobject.h"
|
2012-10-03 23:02:38 +02:00
|
|
|
#include "catalog/pg_largeobject_metadata.h"
|
2010-11-26 23:27:23 +01:00
|
|
|
#include "catalog/pg_namespace.h"
|
2013-01-21 16:06:41 +01:00
|
|
|
#include "catalog/pg_opclass.h"
|
|
|
|
#include "catalog/pg_opfamily.h"
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
#include "catalog/pg_proc.h"
|
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
|
|
|
#include "catalog/pg_statistic_ext.h"
|
2019-11-12 04:00:16 +01:00
|
|
|
#include "catalog/pg_subscription.h"
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
#include "catalog/pg_ts_config.h"
|
|
|
|
#include "catalog/pg_ts_dict.h"
|
|
|
|
#include "catalog/pg_ts_parser.h"
|
|
|
|
#include "catalog/pg_ts_template.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/alter.h"
|
2011-02-12 14:54:13 +01:00
|
|
|
#include "commands/collationcmds.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/conversioncmds.h"
|
|
|
|
#include "commands/dbcommands.h"
|
|
|
|
#include "commands/defrem.h"
|
2012-07-18 16:16:16 +02:00
|
|
|
#include "commands/event_trigger.h"
|
2011-02-08 22:08:41 +01:00
|
|
|
#include "commands/extension.h"
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
#include "commands/policy.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/proclang.h"
|
2017-01-19 18:00:00 +01:00
|
|
|
#include "commands/publicationcmds.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/schemacmds.h"
|
2017-01-19 18:00:00 +01:00
|
|
|
#include "commands/subscriptioncmds.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/tablecmds.h"
|
2004-06-25 23:55:59 +02:00
|
|
|
#include "commands/tablespace.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/trigger.h"
|
2004-06-25 23:55:59 +02:00
|
|
|
#include "commands/typecmds.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "commands/user.h"
|
|
|
|
#include "miscadmin.h"
|
2019-11-12 04:00:16 +01:00
|
|
|
#include "parser/parse_func.h"
|
2013-02-09 05:58:40 +01:00
|
|
|
#include "rewrite/rewriteDefine.h"
|
2003-07-22 21:00:12 +02:00
|
|
|
#include "tcop/utility.h"
|
2010-06-13 19:43:13 +02:00
|
|
|
#include "utils/builtins.h"
|
2012-10-03 23:02:38 +02:00
|
|
|
#include "utils/fmgroids.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
#include "utils/lsyscache.h"
|
2011-02-23 18:18:09 +01:00
|
|
|
#include "utils/rel.h"
|
2010-11-26 23:27:23 +01:00
|
|
|
#include "utils/syscache.h"
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2013-05-29 22:58:43 +02:00
|
|
|
static Oid AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid);
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
/*
|
2013-01-21 16:06:41 +01:00
|
|
|
* Raise an error to the effect that an object of the given name is already
|
|
|
|
* present in the given namespace.
|
2004-06-25 23:55:59 +02:00
|
|
|
*/
|
2013-01-21 16:06:41 +01:00
|
|
|
static void
|
|
|
|
report_name_conflict(Oid classId, const char *name)
|
2003-06-27 16:45:32 +02:00
|
|
|
{
|
2013-05-29 22:58:43 +02:00
|
|
|
char *msgfmt;
|
2013-01-21 16:06:41 +01:00
|
|
|
|
|
|
|
switch (classId)
|
2003-06-27 16:45:32 +02:00
|
|
|
{
|
2013-01-21 16:06:41 +01:00
|
|
|
case EventTriggerRelationId:
|
|
|
|
msgfmt = gettext_noop("event trigger \"%s\" already exists");
|
|
|
|
break;
|
|
|
|
case ForeignDataWrapperRelationId:
|
|
|
|
msgfmt = gettext_noop("foreign-data wrapper \"%s\" already exists");
|
|
|
|
break;
|
|
|
|
case ForeignServerRelationId:
|
|
|
|
msgfmt = gettext_noop("server \"%s\" already exists");
|
|
|
|
break;
|
|
|
|
case LanguageRelationId:
|
|
|
|
msgfmt = gettext_noop("language \"%s\" already exists");
|
|
|
|
break;
|
2017-03-03 16:47:04 +01:00
|
|
|
case PublicationRelationId:
|
|
|
|
msgfmt = gettext_noop("publication \"%s\" already exists");
|
|
|
|
break;
|
|
|
|
case SubscriptionRelationId:
|
|
|
|
msgfmt = gettext_noop("subscription \"%s\" already exists");
|
|
|
|
break;
|
2013-01-21 16:06:41 +01:00
|
|
|
default:
|
|
|
|
elog(ERROR, "unsupported object class %u", classId);
|
|
|
|
break;
|
|
|
|
}
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg(msgfmt, name)));
|
|
|
|
}
|
2011-02-12 14:54:13 +01:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
static void
|
|
|
|
report_namespace_conflict(Oid classId, const char *name, Oid nspOid)
|
|
|
|
{
|
2013-05-29 22:58:43 +02:00
|
|
|
char *msgfmt;
|
2012-03-10 19:19:13 +01:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
Assert(OidIsValid(nspOid));
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
switch (classId)
|
|
|
|
{
|
|
|
|
case ConversionRelationId:
|
|
|
|
Assert(OidIsValid(nspOid));
|
|
|
|
msgfmt = gettext_noop("conversion \"%s\" already exists in schema \"%s\"");
|
|
|
|
break;
|
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
|
|
|
case StatisticExtRelationId:
|
|
|
|
Assert(OidIsValid(nspOid));
|
2017-05-14 16:54:47 +02:00
|
|
|
msgfmt = gettext_noop("statistics object \"%s\" already exists in schema \"%s\"");
|
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
|
|
|
break;
|
2013-01-21 16:06:41 +01:00
|
|
|
case TSParserRelationId:
|
|
|
|
Assert(OidIsValid(nspOid));
|
|
|
|
msgfmt = gettext_noop("text search parser \"%s\" already exists in schema \"%s\"");
|
|
|
|
break;
|
|
|
|
case TSDictionaryRelationId:
|
|
|
|
Assert(OidIsValid(nspOid));
|
|
|
|
msgfmt = gettext_noop("text search dictionary \"%s\" already exists in schema \"%s\"");
|
|
|
|
break;
|
|
|
|
case TSTemplateRelationId:
|
|
|
|
Assert(OidIsValid(nspOid));
|
|
|
|
msgfmt = gettext_noop("text search template \"%s\" already exists in schema \"%s\"");
|
|
|
|
break;
|
|
|
|
case TSConfigRelationId:
|
|
|
|
Assert(OidIsValid(nspOid));
|
|
|
|
msgfmt = gettext_noop("text search configuration \"%s\" already exists in schema \"%s\"");
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unsupported object class %u", classId);
|
|
|
|
break;
|
|
|
|
}
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg(msgfmt, name, get_namespace_name(nspOid))));
|
|
|
|
}
|
2011-12-09 19:42:30 +01:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
/*
|
|
|
|
* AlterObjectRename_internal
|
|
|
|
*
|
|
|
|
* Generic function to rename the given object, for simple cases (won't
|
|
|
|
* work for tables, nor other cases where we need to do more than change
|
|
|
|
* the name column of a single catalog entry).
|
|
|
|
*
|
|
|
|
* rel: catalog relation containing object (RowExclusiveLock'd by caller)
|
|
|
|
* objectId: OID of object to be renamed
|
|
|
|
* new_name: CString representation of new name
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
AlterObjectRename_internal(Relation rel, Oid objectId, const char *new_name)
|
|
|
|
{
|
|
|
|
Oid classId = RelationGetRelid(rel);
|
|
|
|
int oidCacheId = get_object_catcache_oid(classId);
|
|
|
|
int nameCacheId = get_object_catcache_name(classId);
|
|
|
|
AttrNumber Anum_name = get_object_attnum_name(classId);
|
|
|
|
AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
|
|
|
|
AttrNumber Anum_owner = get_object_attnum_owner(classId);
|
|
|
|
HeapTuple oldtup;
|
|
|
|
HeapTuple newtup;
|
|
|
|
Datum datum;
|
|
|
|
bool isnull;
|
|
|
|
Oid namespaceId;
|
|
|
|
Oid ownerId;
|
|
|
|
char *old_name;
|
|
|
|
AclResult aclresult;
|
|
|
|
Datum *values;
|
|
|
|
bool *nulls;
|
|
|
|
bool *replaces;
|
2013-06-13 01:49:50 +02:00
|
|
|
NameData nameattrdata;
|
2011-12-09 19:42:30 +01:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
oldtup = SearchSysCache1(oidCacheId, ObjectIdGetDatum(objectId));
|
|
|
|
if (!HeapTupleIsValid(oldtup))
|
|
|
|
elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
|
|
|
|
objectId, RelationGetRelationName(rel));
|
2012-07-18 16:16:16 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
datum = heap_getattr(oldtup, Anum_name,
|
|
|
|
RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
|
|
|
old_name = NameStr(*(DatumGetName(datum)));
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
/* Get OID of namespace */
|
|
|
|
if (Anum_namespace > 0)
|
|
|
|
{
|
|
|
|
datum = heap_getattr(oldtup, Anum_namespace,
|
|
|
|
RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
|
|
|
namespaceId = DatumGetObjectId(datum);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
namespaceId = InvalidOid;
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
/* Permission checks ... superusers can always do it */
|
|
|
|
if (!superuser())
|
|
|
|
{
|
|
|
|
/* Fail if object does not have an explicit owner */
|
|
|
|
if (Anum_owner <= 0)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
2020-01-30 17:32:04 +01:00
|
|
|
errmsg("must be superuser to rename %s",
|
|
|
|
getObjectDescriptionOids(classId, objectId))));
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
/* Otherwise, must be owner of the existing object */
|
|
|
|
datum = heap_getattr(oldtup, Anum_owner,
|
|
|
|
RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
|
|
|
ownerId = DatumGetObjectId(datum);
|
|
|
|
|
|
|
|
if (!has_privs_of_role(GetUserId(), DatumGetObjectId(ownerId)))
|
2019-11-05 19:40:37 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, get_object_type(classId, objectId),
|
|
|
|
old_name);
|
2013-01-21 16:06:41 +01:00
|
|
|
|
|
|
|
/* User must have CREATE privilege on the namespace */
|
|
|
|
if (OidIsValid(namespaceId))
|
|
|
|
{
|
|
|
|
aclresult = pg_namespace_aclcheck(namespaceId, GetUserId(),
|
|
|
|
ACL_CREATE);
|
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_SCHEMA,
|
2013-01-21 16:06:41 +01:00
|
|
|
get_namespace_name(namespaceId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2013-05-29 22:58:43 +02:00
|
|
|
* Check for duplicate name (more friendly than unique-index failure).
|
|
|
|
* Since this is just a friendliness check, we can just skip it in cases
|
|
|
|
* where there isn't suitable support.
|
|
|
|
*/
|
2013-01-21 16:06:41 +01:00
|
|
|
if (classId == ProcedureRelationId)
|
|
|
|
{
|
|
|
|
Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(oldtup);
|
|
|
|
|
|
|
|
IsThereFunctionInNamespace(new_name, proc->pronargs,
|
2013-06-13 01:50:37 +02:00
|
|
|
&proc->proargtypes, proc->pronamespace);
|
2013-01-21 16:06:41 +01:00
|
|
|
}
|
|
|
|
else if (classId == CollationRelationId)
|
|
|
|
{
|
|
|
|
Form_pg_collation coll = (Form_pg_collation) GETSTRUCT(oldtup);
|
|
|
|
|
|
|
|
IsThereCollationInNamespace(new_name, coll->collnamespace);
|
|
|
|
}
|
|
|
|
else if (classId == OperatorClassRelationId)
|
|
|
|
{
|
|
|
|
Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(oldtup);
|
|
|
|
|
|
|
|
IsThereOpClassInNamespace(new_name, opc->opcmethod,
|
|
|
|
opc->opcnamespace);
|
|
|
|
}
|
|
|
|
else if (classId == OperatorFamilyRelationId)
|
|
|
|
{
|
|
|
|
Form_pg_opfamily opf = (Form_pg_opfamily) GETSTRUCT(oldtup);
|
|
|
|
|
|
|
|
IsThereOpFamilyInNamespace(new_name, opf->opfmethod,
|
|
|
|
opf->opfnamespace);
|
|
|
|
}
|
2017-03-03 16:47:04 +01:00
|
|
|
else if (classId == SubscriptionRelationId)
|
|
|
|
{
|
|
|
|
if (SearchSysCacheExists2(SUBSCRIPTIONNAME, MyDatabaseId,
|
|
|
|
CStringGetDatum(new_name)))
|
|
|
|
report_name_conflict(classId, new_name);
|
Add an enforcement mechanism for global object names in regression tests.
In commit 18555b132 we tentatively established a rule that regression
tests should use names containing "regression" for databases, and names
starting with "regress_" for all other globally-visible object names, so
as to circumscribe the side-effects that "make installcheck" could have
on an existing installation.
This commit adds a simple enforcement mechanism for that rule: if the code
is compiled with ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS defined, it
will emit a warning (not an error) whenever a database, role, tablespace,
subscription, or replication origin name is created that doesn't obey the
rule. Running one or more buildfarm members with that symbol defined
should be enough to catch new violations, at least in the regular
regression tests. Most TAP tests wouldn't notice such warnings, but
that's actually fine because TAP tests don't execute against an existing
server anyway.
Since it's already the case that running src/test/modules/ tests in
installcheck mode is deprecated, we can use that as a home for tests
that seem unsafe to run against an existing server, such as tests that
might have side-effects on existing roles. Document that (though this
commit doesn't in itself make it any less safe than before).
Update regress.sgml to define these restrictions more clearly, and
to clean up assorted lack-of-up-to-date-ness in its descriptions of
the available regression tests.
Discussion: https://postgr.es/m/16638.1468620817@sss.pgh.pa.us
2019-06-29 17:34:00 +02:00
|
|
|
|
|
|
|
/* Also enforce regression testing naming rules, if enabled */
|
|
|
|
#ifdef ENFORCE_REGRESSION_TEST_NAME_RESTRICTIONS
|
|
|
|
if (strncmp(new_name, "regress_", 8) != 0)
|
|
|
|
elog(WARNING, "subscriptions created by regression test cases should have names starting with \"regress_\"");
|
|
|
|
#endif
|
2017-03-03 16:47:04 +01:00
|
|
|
}
|
2013-01-21 16:06:41 +01:00
|
|
|
else if (nameCacheId >= 0)
|
|
|
|
{
|
|
|
|
if (OidIsValid(namespaceId))
|
|
|
|
{
|
|
|
|
if (SearchSysCacheExists2(nameCacheId,
|
|
|
|
CStringGetDatum(new_name),
|
|
|
|
ObjectIdGetDatum(namespaceId)))
|
|
|
|
report_namespace_conflict(classId, new_name, namespaceId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (SearchSysCacheExists1(nameCacheId,
|
|
|
|
CStringGetDatum(new_name)))
|
|
|
|
report_name_conflict(classId, new_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Build modified tuple */
|
|
|
|
values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
|
|
|
|
nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
|
|
|
|
replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
|
2013-06-13 01:49:50 +02:00
|
|
|
namestrcpy(&nameattrdata, new_name);
|
|
|
|
values[Anum_name - 1] = NameGetDatum(&nameattrdata);
|
2013-01-21 16:06:41 +01:00
|
|
|
replaces[Anum_name - 1] = true;
|
|
|
|
newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
|
|
|
|
values, nulls, replaces);
|
|
|
|
|
|
|
|
/* Perform actual update */
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &oldtup->t_self, newtup);
|
2013-01-21 16:06:41 +01:00
|
|
|
|
2013-03-18 03:55:14 +01:00
|
|
|
InvokeObjectPostAlterHook(classId, objectId, 0);
|
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
/* Release memory */
|
|
|
|
pfree(values);
|
|
|
|
pfree(nulls);
|
|
|
|
pfree(replaces);
|
|
|
|
heap_freetuple(newtup);
|
|
|
|
|
|
|
|
ReleaseSysCache(oldtup);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2014-05-06 18:12:18 +02:00
|
|
|
* Executes an ALTER OBJECT / RENAME TO statement. Based on the object
|
2013-01-21 16:06:41 +01:00
|
|
|
* type, the function appropriate to that type is executed.
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
*
|
|
|
|
* Return value is the address of the renamed object.
|
2013-01-21 16:06:41 +01:00
|
|
|
*/
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
ObjectAddress
|
2013-01-21 16:06:41 +01:00
|
|
|
ExecRenameStmt(RenameStmt *stmt)
|
|
|
|
{
|
|
|
|
switch (stmt->renameType)
|
|
|
|
{
|
2014-12-23 13:06:44 +01:00
|
|
|
case OBJECT_TABCONSTRAINT:
|
|
|
|
case OBJECT_DOMCONSTRAINT:
|
2013-01-21 16:06:41 +01:00
|
|
|
return RenameConstraint(stmt);
|
|
|
|
|
|
|
|
case OBJECT_DATABASE:
|
|
|
|
return RenameDatabase(stmt->subname, stmt->newname);
|
2007-01-23 06:07:18 +01:00
|
|
|
|
2005-06-28 07:09:14 +02:00
|
|
|
case OBJECT_ROLE:
|
2012-12-24 00:25:03 +01:00
|
|
|
return RenameRole(stmt->subname, stmt->newname);
|
2005-06-28 07:09:14 +02:00
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
case OBJECT_SCHEMA:
|
2012-12-24 00:25:03 +01:00
|
|
|
return RenameSchema(stmt->subname, stmt->newname);
|
2003-06-27 16:45:32 +02:00
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
case OBJECT_TABLESPACE:
|
2012-12-24 00:25:03 +01:00
|
|
|
return RenameTableSpace(stmt->subname, stmt->newname);
|
2004-06-25 23:55:59 +02:00
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
case OBJECT_TABLE:
|
2007-07-03 03:30:37 +02:00
|
|
|
case OBJECT_SEQUENCE:
|
|
|
|
case OBJECT_VIEW:
|
2013-03-04 01:23:31 +01:00
|
|
|
case OBJECT_MATVIEW:
|
2004-08-22 02:08:28 +02:00
|
|
|
case OBJECT_INDEX:
|
Improve behavior of concurrent rename statements.
Previously, renaming a table, sequence, view, index, foreign table,
column, or trigger checked permissions before locking the object, which
meant that if permissions were revoked during the lock wait, we would
still allow the operation. Similarly, if the original object is dropped
and a new one with the same name is created, the operation will be allowed
if we had permissions on the old object; the permissions on the new
object don't matter. All this is now fixed.
Along the way, attempting to rename a trigger on a foreign table now gives
the same error message as trying to create one there in the first place
(i.e. that it's not a table or view) rather than simply stating that no
trigger by that name exists.
Patch by me; review by Noah Misch.
2011-12-16 00:51:46 +01:00
|
|
|
case OBJECT_FOREIGN_TABLE:
|
2012-12-24 00:25:03 +01:00
|
|
|
return RenameRelation(stmt);
|
Improve behavior of concurrent rename statements.
Previously, renaming a table, sequence, view, index, foreign table,
column, or trigger checked permissions before locking the object, which
meant that if permissions were revoked during the lock wait, we would
still allow the operation. Similarly, if the original object is dropped
and a new one with the same name is created, the operation will be allowed
if we had permissions on the old object; the permissions on the new
object don't matter. All this is now fixed.
Along the way, attempting to rename a trigger on a foreign table now gives
the same error message as trying to create one there in the first place
(i.e. that it's not a table or view) rather than simply stating that no
trigger by that name exists.
Patch by me; review by Noah Misch.
2011-12-16 00:51:46 +01:00
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
case OBJECT_COLUMN:
|
2010-09-26 13:41:03 +02:00
|
|
|
case OBJECT_ATTRIBUTE:
|
2012-12-24 00:25:03 +01:00
|
|
|
return renameatt(stmt);
|
Improve behavior of concurrent rename statements.
Previously, renaming a table, sequence, view, index, foreign table,
column, or trigger checked permissions before locking the object, which
meant that if permissions were revoked during the lock wait, we would
still allow the operation. Similarly, if the original object is dropped
and a new one with the same name is created, the operation will be allowed
if we had permissions on the old object; the permissions on the new
object don't matter. All this is now fixed.
Along the way, attempting to rename a trigger on a foreign table now gives
the same error message as trying to create one there in the first place
(i.e. that it's not a table or view) rather than simply stating that no
trigger by that name exists.
Patch by me; review by Noah Misch.
2011-12-16 00:51:46 +01:00
|
|
|
|
2013-02-09 05:58:40 +01:00
|
|
|
case OBJECT_RULE:
|
|
|
|
return RenameRewriteRule(stmt->relation, stmt->subname,
|
|
|
|
stmt->newname);
|
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
case OBJECT_TRIGGER:
|
2012-12-24 00:25:03 +01:00
|
|
|
return renametrig(stmt);
|
2003-06-27 16:45:32 +02:00
|
|
|
|
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
|
|
|
case OBJECT_POLICY:
|
|
|
|
return rename_policy(stmt);
|
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
case OBJECT_DOMAIN:
|
|
|
|
case OBJECT_TYPE:
|
|
|
|
return RenameType(stmt);
|
2007-08-21 03:11:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
case OBJECT_AGGREGATE:
|
|
|
|
case OBJECT_COLLATION:
|
|
|
|
case OBJECT_CONVERSION:
|
|
|
|
case OBJECT_EVENT_TRIGGER:
|
|
|
|
case OBJECT_FDW:
|
|
|
|
case OBJECT_FOREIGN_SERVER:
|
|
|
|
case OBJECT_FUNCTION:
|
|
|
|
case OBJECT_OPCLASS:
|
|
|
|
case OBJECT_OPFAMILY:
|
|
|
|
case OBJECT_LANGUAGE:
|
2017-11-30 14:46:13 +01:00
|
|
|
case OBJECT_PROCEDURE:
|
|
|
|
case OBJECT_ROUTINE:
|
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
|
|
|
case OBJECT_STATISTIC_EXT:
|
2013-01-21 16:06:41 +01:00
|
|
|
case OBJECT_TSCONFIGURATION:
|
2007-08-21 03:11:32 +02:00
|
|
|
case OBJECT_TSDICTIONARY:
|
2013-01-21 16:06:41 +01:00
|
|
|
case OBJECT_TSPARSER:
|
2007-08-21 03:11:32 +02:00
|
|
|
case OBJECT_TSTEMPLATE:
|
2017-03-03 16:47:04 +01:00
|
|
|
case OBJECT_PUBLICATION:
|
|
|
|
case OBJECT_SUBSCRIPTION:
|
2013-01-21 16:06:41 +01:00
|
|
|
{
|
2013-05-29 22:58:43 +02:00
|
|
|
ObjectAddress address;
|
|
|
|
Relation catalog;
|
|
|
|
Relation relation;
|
2007-08-21 03:11:32 +02:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
address = get_object_address(stmt->renameType,
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
stmt->object,
|
2013-01-21 16:06:41 +01:00
|
|
|
&relation,
|
|
|
|
AccessExclusiveLock, false);
|
|
|
|
Assert(relation == NULL);
|
2007-08-21 03:11:32 +02:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
catalog = table_open(address.classId, RowExclusiveLock);
|
2013-01-21 16:06:41 +01:00
|
|
|
AlterObjectRename_internal(catalog,
|
|
|
|
address.objectId,
|
|
|
|
stmt->newname);
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(catalog, RowExclusiveLock);
|
2013-01-21 16:06:41 +01:00
|
|
|
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
return address;
|
2013-01-21 16:06:41 +01:00
|
|
|
}
|
2008-03-19 19:38:30 +01:00
|
|
|
|
2003-06-27 16:45:32 +02:00
|
|
|
default:
|
2003-07-20 23:56:35 +02:00
|
|
|
elog(ERROR, "unrecognized rename stmt type: %d",
|
|
|
|
(int) stmt->renameType);
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
return InvalidObjectAddress; /* keep compiler happy */
|
2003-06-27 16:45:32 +02:00
|
|
|
}
|
|
|
|
}
|
2004-06-25 23:55:59 +02:00
|
|
|
|
2016-04-05 23:38:54 +02:00
|
|
|
/*
|
|
|
|
* Executes an ALTER OBJECT / DEPENDS ON [EXTENSION] statement.
|
|
|
|
*
|
|
|
|
* Return value is the address of the altered object. refAddress is an output
|
|
|
|
* argument which, if not null, receives the address of the object that the
|
|
|
|
* altered object now depends on.
|
|
|
|
*/
|
|
|
|
ObjectAddress
|
|
|
|
ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddress)
|
|
|
|
{
|
2016-06-10 00:02:36 +02:00
|
|
|
ObjectAddress address;
|
|
|
|
ObjectAddress refAddr;
|
|
|
|
Relation rel;
|
2016-04-05 23:38:54 +02:00
|
|
|
|
|
|
|
address =
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
get_object_address_rv(stmt->objectType, stmt->relation, (List *) stmt->object,
|
2017-05-17 22:31:56 +02:00
|
|
|
&rel, AccessExclusiveLock, false);
|
2016-04-05 23:38:54 +02:00
|
|
|
|
|
|
|
/*
|
2016-06-10 00:02:36 +02:00
|
|
|
* If a relation was involved, it would have been opened and locked. We
|
|
|
|
* don't need the relation here, but we'll retain the lock until commit.
|
2016-04-05 23:38:54 +02:00
|
|
|
*/
|
|
|
|
if (rel)
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, NoLock);
|
2016-04-05 23:38:54 +02:00
|
|
|
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
refAddr = get_object_address(OBJECT_EXTENSION, (Node *) stmt->extname,
|
|
|
|
&rel, AccessExclusiveLock, false);
|
2016-04-05 23:38:54 +02:00
|
|
|
Assert(rel == NULL);
|
|
|
|
if (refAddress)
|
|
|
|
*refAddress = refAddr;
|
|
|
|
|
2016-04-10 16:03:35 +02:00
|
|
|
recordDependencyOn(&address, &refAddr, DEPENDENCY_AUTO_EXTENSION);
|
2016-04-05 23:38:54 +02:00
|
|
|
|
|
|
|
return address;
|
|
|
|
}
|
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
/*
|
|
|
|
* Executes an ALTER OBJECT / SET SCHEMA statement. Based on the object
|
|
|
|
* type, the function appropriate to that type is executed.
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
*
|
|
|
|
* Return value is that of the altered object.
|
|
|
|
*
|
|
|
|
* oldSchemaAddr is an output argument which, if not NULL, is set to the object
|
|
|
|
* address of the original schema.
|
2005-08-01 06:03:59 +02:00
|
|
|
*/
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
ObjectAddress
|
|
|
|
ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt,
|
|
|
|
ObjectAddress *oldSchemaAddr)
|
2005-08-01 06:03:59 +02:00
|
|
|
{
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
ObjectAddress address;
|
|
|
|
Oid oldNspOid;
|
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
switch (stmt->objectType)
|
|
|
|
{
|
2011-02-08 22:08:41 +01:00
|
|
|
case OBJECT_EXTENSION:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
address = AlterExtensionNamespace(strVal((Value *) stmt->object), stmt->newschema,
|
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
|
|
|
oldSchemaAddr ? &oldNspOid : NULL);
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
break;
|
2011-02-08 22:08:41 +01:00
|
|
|
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
case OBJECT_FOREIGN_TABLE:
|
2005-08-01 06:03:59 +02:00
|
|
|
case OBJECT_SEQUENCE:
|
|
|
|
case OBJECT_TABLE:
|
2008-06-15 03:25:54 +02:00
|
|
|
case OBJECT_VIEW:
|
2013-03-04 01:23:31 +01:00
|
|
|
case OBJECT_MATVIEW:
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
address = AlterTableNamespace(stmt,
|
|
|
|
oldSchemaAddr ? &oldNspOid : NULL);
|
|
|
|
break;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2012-09-27 23:13:09 +02:00
|
|
|
case OBJECT_DOMAIN:
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
case OBJECT_TYPE:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
address = AlterTypeNamespace(castNode(List, stmt->object), stmt->newschema,
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
stmt->objectType,
|
|
|
|
oldSchemaAddr ? &oldNspOid : NULL);
|
|
|
|
break;
|
2010-11-26 23:27:23 +01:00
|
|
|
|
2012-09-27 23:13:09 +02:00
|
|
|
/* generic code path */
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
case OBJECT_AGGREGATE:
|
|
|
|
case OBJECT_COLLATION:
|
2012-09-27 23:13:09 +02:00
|
|
|
case OBJECT_CONVERSION:
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
case OBJECT_FUNCTION:
|
2012-09-27 23:13:09 +02:00
|
|
|
case OBJECT_OPERATOR:
|
|
|
|
case OBJECT_OPCLASS:
|
|
|
|
case OBJECT_OPFAMILY:
|
2017-11-30 14:46:13 +01:00
|
|
|
case OBJECT_PROCEDURE:
|
|
|
|
case OBJECT_ROUTINE:
|
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
|
|
|
case OBJECT_STATISTIC_EXT:
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
case OBJECT_TSCONFIGURATION:
|
2010-11-26 23:27:23 +01:00
|
|
|
case OBJECT_TSDICTIONARY:
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
case OBJECT_TSPARSER:
|
2010-11-26 23:27:23 +01:00
|
|
|
case OBJECT_TSTEMPLATE:
|
2012-09-27 23:13:09 +02:00
|
|
|
{
|
|
|
|
Relation catalog;
|
|
|
|
Relation relation;
|
|
|
|
Oid classId;
|
|
|
|
Oid nspOid;
|
|
|
|
|
|
|
|
address = get_object_address(stmt->objectType,
|
|
|
|
stmt->object,
|
|
|
|
&relation,
|
|
|
|
AccessExclusiveLock,
|
|
|
|
false);
|
|
|
|
Assert(relation == NULL);
|
|
|
|
classId = address.classId;
|
2019-01-21 19:32:19 +01:00
|
|
|
catalog = table_open(classId, RowExclusiveLock);
|
2012-09-27 23:13:09 +02:00
|
|
|
nspOid = LookupCreationNamespace(stmt->newschema);
|
|
|
|
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
oldNspOid = AlterObjectNamespace_internal(catalog, address.objectId,
|
|
|
|
nspOid);
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(catalog, RowExclusiveLock);
|
2012-09-27 23:13:09 +02:00
|
|
|
}
|
2005-08-01 06:03:59 +02:00
|
|
|
break;
|
2005-10-15 04:49:52 +02:00
|
|
|
|
2005-08-01 06:03:59 +02:00
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized AlterObjectSchemaStmt type: %d",
|
|
|
|
(int) stmt->objectType);
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
return InvalidObjectAddress; /* keep compiler happy */
|
2005-08-01 06:03:59 +02:00
|
|
|
}
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
|
|
|
|
if (oldSchemaAddr)
|
|
|
|
ObjectAddressSet(*oldSchemaAddr, NamespaceRelationId, oldNspOid);
|
|
|
|
|
|
|
|
return address;
|
2005-08-01 06:03:59 +02:00
|
|
|
}
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/*
|
|
|
|
* Change an object's namespace given its classOid and object Oid.
|
|
|
|
*
|
|
|
|
* Objects that don't have a namespace should be ignored.
|
|
|
|
*
|
|
|
|
* This function is currently used only by ALTER EXTENSION SET SCHEMA,
|
|
|
|
* so it only needs to cover object types that can be members of an
|
|
|
|
* extension, and it doesn't have to deal with certain special cases
|
|
|
|
* such as not wanting to process array types --- those should never
|
2017-05-14 19:32:59 +02:00
|
|
|
* be direct members of an extension anyway. Nonetheless, we insist
|
|
|
|
* on listing all OCLASS types in the switch.
|
2011-02-08 22:08:41 +01:00
|
|
|
*
|
|
|
|
* Returns the OID of the object's previous namespace, or InvalidOid if
|
|
|
|
* object doesn't have a schema.
|
|
|
|
*/
|
|
|
|
Oid
|
2012-10-31 14:52:55 +01:00
|
|
|
AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
|
|
|
|
ObjectAddresses *objsMoved)
|
2011-02-08 22:08:41 +01:00
|
|
|
{
|
|
|
|
Oid oldNspOid = InvalidOid;
|
|
|
|
ObjectAddress dep;
|
|
|
|
|
|
|
|
dep.classId = classId;
|
|
|
|
dep.objectId = objid;
|
|
|
|
dep.objectSubId = 0;
|
|
|
|
|
|
|
|
switch (getObjectClass(&dep))
|
|
|
|
{
|
|
|
|
case OCLASS_CLASS:
|
2011-04-10 17:42:00 +02:00
|
|
|
{
|
|
|
|
Relation rel;
|
2011-02-08 22:08:41 +01:00
|
|
|
|
2011-04-10 17:42:00 +02:00
|
|
|
rel = relation_open(objid, AccessExclusiveLock);
|
|
|
|
oldNspOid = RelationGetNamespace(rel);
|
2011-02-08 22:08:41 +01:00
|
|
|
|
2012-10-31 14:52:55 +01:00
|
|
|
AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
|
2011-02-08 22:08:41 +01:00
|
|
|
|
2011-04-10 17:42:00 +02:00
|
|
|
relation_close(rel, NoLock);
|
|
|
|
break;
|
|
|
|
}
|
2011-02-08 22:08:41 +01:00
|
|
|
|
|
|
|
case OCLASS_TYPE:
|
2012-10-31 14:52:55 +01:00
|
|
|
oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
|
2011-02-08 22:08:41 +01:00
|
|
|
break;
|
|
|
|
|
2017-05-14 19:32:59 +02:00
|
|
|
case OCLASS_PROC:
|
2011-02-12 14:54:13 +01:00
|
|
|
case OCLASS_COLLATION:
|
2011-02-08 22:08:41 +01:00
|
|
|
case OCLASS_CONVERSION:
|
|
|
|
case OCLASS_OPERATOR:
|
|
|
|
case OCLASS_OPCLASS:
|
|
|
|
case OCLASS_OPFAMILY:
|
2017-05-14 19:32:59 +02:00
|
|
|
case OCLASS_STATISTIC_EXT:
|
2011-02-08 22:08:41 +01:00
|
|
|
case OCLASS_TSPARSER:
|
|
|
|
case OCLASS_TSDICT:
|
|
|
|
case OCLASS_TSTEMPLATE:
|
|
|
|
case OCLASS_TSCONFIG:
|
2012-09-27 23:13:09 +02:00
|
|
|
{
|
|
|
|
Relation catalog;
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
catalog = table_open(classId, RowExclusiveLock);
|
2012-09-27 23:13:09 +02:00
|
|
|
|
|
|
|
oldNspOid = AlterObjectNamespace_internal(catalog, objid,
|
|
|
|
nspOid);
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(catalog, RowExclusiveLock);
|
2012-09-27 23:13:09 +02:00
|
|
|
}
|
2011-02-08 22:08:41 +01:00
|
|
|
break;
|
|
|
|
|
2017-05-14 19:32:59 +02:00
|
|
|
case OCLASS_CAST:
|
|
|
|
case OCLASS_CONSTRAINT:
|
|
|
|
case OCLASS_DEFAULT:
|
|
|
|
case OCLASS_LANGUAGE:
|
|
|
|
case OCLASS_LARGEOBJECT:
|
|
|
|
case OCLASS_AM:
|
|
|
|
case OCLASS_AMOP:
|
|
|
|
case OCLASS_AMPROC:
|
|
|
|
case OCLASS_REWRITE:
|
|
|
|
case OCLASS_TRIGGER:
|
|
|
|
case OCLASS_SCHEMA:
|
|
|
|
case OCLASS_ROLE:
|
|
|
|
case OCLASS_DATABASE:
|
|
|
|
case OCLASS_TBLSPACE:
|
|
|
|
case OCLASS_FDW:
|
|
|
|
case OCLASS_FOREIGN_SERVER:
|
|
|
|
case OCLASS_USER_MAPPING:
|
|
|
|
case OCLASS_DEFACL:
|
|
|
|
case OCLASS_EXTENSION:
|
|
|
|
case OCLASS_EVENT_TRIGGER:
|
|
|
|
case OCLASS_POLICY:
|
|
|
|
case OCLASS_PUBLICATION:
|
|
|
|
case OCLASS_PUBLICATION_REL:
|
|
|
|
case OCLASS_SUBSCRIPTION:
|
|
|
|
case OCLASS_TRANSFORM:
|
|
|
|
/* ignore object types that don't have schema-qualified names */
|
2011-02-08 22:08:41 +01:00
|
|
|
break;
|
2017-05-14 19:32:59 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* There's intentionally no default: case here; we want the
|
|
|
|
* compiler to warn if a new OCLASS hasn't been handled above.
|
|
|
|
*/
|
2011-02-08 22:08:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return oldNspOid;
|
|
|
|
}
|
|
|
|
|
2010-11-26 23:27:23 +01:00
|
|
|
/*
|
|
|
|
* Generic function to change the namespace of a given object, for simple
|
2011-02-08 22:08:41 +01:00
|
|
|
* cases (won't work for tables, nor other cases where we need to do more
|
|
|
|
* than change the namespace column of a single catalog entry).
|
2010-11-26 23:27:23 +01:00
|
|
|
*
|
2011-02-08 22:08:41 +01:00
|
|
|
* rel: catalog relation containing object (RowExclusiveLock'd by caller)
|
|
|
|
* objid: OID of object to change the namespace of
|
|
|
|
* nspOid: OID of new namespace
|
|
|
|
*
|
|
|
|
* Returns the OID of the object's previous namespace.
|
2010-11-26 23:27:23 +01:00
|
|
|
*/
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
static Oid
|
2012-09-27 23:13:09 +02:00
|
|
|
AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
|
2010-11-26 23:27:23 +01:00
|
|
|
{
|
2011-02-08 22:08:41 +01:00
|
|
|
Oid classId = RelationGetRelid(rel);
|
2012-09-27 23:13:09 +02:00
|
|
|
int oidCacheId = get_object_catcache_oid(classId);
|
|
|
|
int nameCacheId = get_object_catcache_name(classId);
|
|
|
|
AttrNumber Anum_name = get_object_attnum_name(classId);
|
|
|
|
AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
|
|
|
|
AttrNumber Anum_owner = get_object_attnum_owner(classId);
|
2010-11-26 23:27:23 +01:00
|
|
|
Oid oldNspOid;
|
2011-04-10 17:42:00 +02:00
|
|
|
Datum name,
|
|
|
|
namespace;
|
|
|
|
bool isnull;
|
|
|
|
HeapTuple tup,
|
|
|
|
newtup;
|
2010-11-26 23:27:23 +01:00
|
|
|
Datum *values;
|
|
|
|
bool *nulls;
|
|
|
|
bool *replaces;
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
tup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objid));
|
2010-11-26 23:27:23 +01:00
|
|
|
if (!HeapTupleIsValid(tup)) /* should not happen */
|
2011-02-08 22:08:41 +01:00
|
|
|
elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
|
|
|
|
objid, RelationGetRelationName(rel));
|
2010-11-26 23:27:23 +01:00
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
name = heap_getattr(tup, Anum_name, RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
2012-09-27 23:13:09 +02:00
|
|
|
namespace = heap_getattr(tup, Anum_namespace, RelationGetDescr(rel),
|
|
|
|
&isnull);
|
2011-02-08 22:08:41 +01:00
|
|
|
Assert(!isnull);
|
2010-11-26 23:27:23 +01:00
|
|
|
oldNspOid = DatumGetObjectId(namespace);
|
|
|
|
|
2015-11-19 16:49:25 +01:00
|
|
|
/*
|
2016-06-10 00:02:36 +02:00
|
|
|
* If the object is already in the correct namespace, we don't need to do
|
|
|
|
* anything except fire the object access hook.
|
2015-11-19 16:49:25 +01:00
|
|
|
*/
|
|
|
|
if (oldNspOid == nspOid)
|
|
|
|
{
|
|
|
|
InvokeObjectPostAlterHook(classId, objid, 0);
|
|
|
|
return oldNspOid;
|
|
|
|
}
|
|
|
|
|
2010-11-26 23:27:23 +01:00
|
|
|
/* Check basic namespace related issues */
|
2015-11-19 16:49:25 +01:00
|
|
|
CheckSetNamespace(oldNspOid, nspOid);
|
2010-11-26 23:27:23 +01:00
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* Permission checks ... superusers can always do it */
|
2010-11-26 23:27:23 +01:00
|
|
|
if (!superuser())
|
|
|
|
{
|
2011-04-10 17:42:00 +02:00
|
|
|
Datum owner;
|
2010-11-26 23:27:23 +01:00
|
|
|
Oid ownerId;
|
|
|
|
AclResult aclresult;
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* Fail if object does not have an explicit owner */
|
|
|
|
if (Anum_owner <= 0)
|
2010-11-26 23:27:23 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
2020-01-30 17:32:04 +01:00
|
|
|
errmsg("must be superuser to set schema of %s",
|
|
|
|
getObjectDescriptionOids(classId, objid))));
|
2010-11-26 23:27:23 +01:00
|
|
|
|
|
|
|
/* Otherwise, must be owner of the existing object */
|
2011-02-08 22:08:41 +01:00
|
|
|
owner = heap_getattr(tup, Anum_owner, RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
2010-11-26 23:27:23 +01:00
|
|
|
ownerId = DatumGetObjectId(owner);
|
|
|
|
|
|
|
|
if (!has_privs_of_role(GetUserId(), ownerId))
|
2019-11-05 19:40:37 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, get_object_type(classId, objid),
|
2010-11-26 23:27:23 +01:00
|
|
|
NameStr(*(DatumGetName(name))));
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* User must have CREATE privilege on new namespace */
|
|
|
|
aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
|
2010-11-26 23:27:23 +01:00
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_SCHEMA,
|
2011-02-08 22:08:41 +01:00
|
|
|
get_namespace_name(nspOid));
|
2010-11-26 23:27:23 +01:00
|
|
|
}
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/*
|
|
|
|
* Check for duplicate name (more friendly than unique-index failure).
|
|
|
|
* Since this is just a friendliness check, we can just skip it in cases
|
2013-01-21 16:06:41 +01:00
|
|
|
* where there isn't suitable support.
|
2011-02-08 22:08:41 +01:00
|
|
|
*/
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
if (classId == ProcedureRelationId)
|
|
|
|
{
|
2013-01-21 16:06:41 +01:00
|
|
|
Form_pg_proc proc = (Form_pg_proc) GETSTRUCT(tup);
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
|
|
|
|
IsThereFunctionInNamespace(NameStr(proc->proname), proc->pronargs,
|
2013-06-13 01:50:37 +02:00
|
|
|
&proc->proargtypes, nspOid);
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
}
|
|
|
|
else if (classId == CollationRelationId)
|
|
|
|
{
|
2013-01-21 16:06:41 +01:00
|
|
|
Form_pg_collation coll = (Form_pg_collation) GETSTRUCT(tup);
|
|
|
|
|
|
|
|
IsThereCollationInNamespace(NameStr(coll->collname), nspOid);
|
|
|
|
}
|
|
|
|
else if (classId == OperatorClassRelationId)
|
|
|
|
{
|
|
|
|
Form_pg_opclass opc = (Form_pg_opclass) GETSTRUCT(tup);
|
|
|
|
|
|
|
|
IsThereOpClassInNamespace(NameStr(opc->opcname),
|
|
|
|
opc->opcmethod, nspOid);
|
|
|
|
}
|
|
|
|
else if (classId == OperatorFamilyRelationId)
|
|
|
|
{
|
|
|
|
Form_pg_opfamily opf = (Form_pg_opfamily) GETSTRUCT(tup);
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
IsThereOpFamilyInNamespace(NameStr(opf->opfname),
|
|
|
|
opf->opfmethod, nspOid);
|
Rework order of checks in ALTER / SET SCHEMA
When attempting to move an object into the schema in which it already
was, for most objects classes we were correctly complaining about
exactly that ("object is already in schema"); but for some other object
classes, such as functions, we were instead complaining of a name
collision ("object already exists in schema"). The latter is wrong and
misleading, per complaint from Robert Haas in
CA+TgmoZ0+gNf7RDKRc3u5rHXffP=QjqPZKGxb4BsPz65k7qnHQ@mail.gmail.com
To fix, refactor the way these checks are done. As a bonus, the
resulting code is smaller and can also share some code with Rename
cases.
While at it, remove use of getObjectDescriptionOids() in error messages.
These are normally disallowed because of translatability considerations,
but this one had slipped through since 9.1. (Not sure that this is
worth backpatching, though, as it would create some untranslated
messages in back branches.)
This is loosely based on a patch by KaiGai Kohei, heavily reworked by
me.
2013-01-15 17:23:43 +01:00
|
|
|
}
|
|
|
|
else if (nameCacheId >= 0 &&
|
|
|
|
SearchSysCacheExists2(nameCacheId, name,
|
|
|
|
ObjectIdGetDatum(nspOid)))
|
|
|
|
report_namespace_conflict(classId,
|
|
|
|
NameStr(*(DatumGetName(name))),
|
|
|
|
nspOid);
|
2011-02-08 22:08:41 +01:00
|
|
|
|
|
|
|
/* Build modified tuple */
|
|
|
|
values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
|
|
|
|
nulls = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
|
|
|
|
replaces = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(bool));
|
|
|
|
values[Anum_namespace - 1] = ObjectIdGetDatum(nspOid);
|
2010-11-26 23:27:23 +01:00
|
|
|
replaces[Anum_namespace - 1] = true;
|
2011-02-08 22:08:41 +01:00
|
|
|
newtup = heap_modify_tuple(tup, RelationGetDescr(rel),
|
|
|
|
values, nulls, replaces);
|
2010-11-26 23:27:23 +01:00
|
|
|
|
|
|
|
/* Perform actual update */
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &tup->t_self, newtup);
|
2010-11-26 23:27:23 +01:00
|
|
|
|
|
|
|
/* Release memory */
|
|
|
|
pfree(values);
|
|
|
|
pfree(nulls);
|
|
|
|
pfree(replaces);
|
|
|
|
|
|
|
|
/* update dependencies to point to the new schema */
|
|
|
|
changeDependencyFor(classId, objid,
|
|
|
|
NamespaceRelationId, oldNspOid, nspOid);
|
2011-02-08 22:08:41 +01:00
|
|
|
|
2013-03-18 03:55:14 +01:00
|
|
|
InvokeObjectPostAlterHook(classId, objid, 0);
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
return oldNspOid;
|
2010-11-26 23:27:23 +01:00
|
|
|
}
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
/*
|
|
|
|
* Executes an ALTER OBJECT / OWNER TO statement. Based on the object
|
|
|
|
* type, the function appropriate to that type is executed.
|
|
|
|
*/
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
ObjectAddress
|
2004-06-25 23:55:59 +02:00
|
|
|
ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|
|
|
{
|
Allow CURRENT/SESSION_USER to be used in certain commands
Commands such as ALTER USER, ALTER GROUP, ALTER ROLE, GRANT, and the
various ALTER OBJECT / OWNER TO, as well as ad-hoc clauses related to
roles such as the AUTHORIZATION clause of CREATE SCHEMA, the FOR clause
of CREATE USER MAPPING, and the FOR ROLE clause of ALTER DEFAULT
PRIVILEGES can now take the keywords CURRENT_USER and SESSION_USER as
user specifiers in place of an explicit user name.
This commit also fixes some quite ugly handling of special standards-
mandated syntax in CREATE USER MAPPING, which in particular would fail
to work in presence of a role named "current_user".
The special role specifiers PUBLIC and NONE also have more consistent
handling now.
Also take the opportunity to add location tracking to user specifiers.
Authors: Kyotaro Horiguchi. Heavily reworked by Álvaro Herrera.
Reviewed by: Rushabh Lathia, Adam Brightwell, Marti Raudsepp.
2015-03-09 19:41:54 +01:00
|
|
|
Oid newowner = get_rolespec_oid(stmt->newowner, false);
|
2004-06-25 23:55:59 +02:00
|
|
|
|
|
|
|
switch (stmt->objectType)
|
|
|
|
{
|
|
|
|
case OBJECT_DATABASE:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterDatabaseOwner(strVal((Value *) stmt->object), newowner);
|
2004-06-25 23:55:59 +02:00
|
|
|
|
|
|
|
case OBJECT_SCHEMA:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterSchemaOwner(strVal((Value *) stmt->object), newowner);
|
2004-06-25 23:55:59 +02:00
|
|
|
|
|
|
|
case OBJECT_TYPE:
|
|
|
|
case OBJECT_DOMAIN: /* same as TYPE */
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterTypeOwner(castNode(List, stmt->object), newowner, stmt->objectType);
|
|
|
|
break;
|
2004-06-25 23:55:59 +02:00
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
case OBJECT_FDW:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterForeignDataWrapperOwner(strVal((Value *) stmt->object),
|
2012-12-24 00:25:03 +01:00
|
|
|
newowner);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
case OBJECT_FOREIGN_SERVER:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterForeignServerOwner(strVal((Value *) stmt->object),
|
2012-12-24 00:25:03 +01:00
|
|
|
newowner);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2012-07-18 16:16:16 +02:00
|
|
|
case OBJECT_EVENT_TRIGGER:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterEventTriggerOwner(strVal((Value *) stmt->object),
|
2012-12-24 00:25:03 +01:00
|
|
|
newowner);
|
2012-07-18 16:16:16 +02:00
|
|
|
|
2017-01-19 18:00:00 +01:00
|
|
|
case OBJECT_PUBLICATION:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterPublicationOwner(strVal((Value *) stmt->object),
|
2017-01-19 18:00:00 +01:00
|
|
|
newowner);
|
|
|
|
|
|
|
|
case OBJECT_SUBSCRIPTION:
|
Remove objname/objargs split for referring to objects
In simpler times, it might have worked to refer to all kinds of objects
by a list of name components and an optional argument list. But this
doesn't work for all objects, which has resulted in a collection of
hacks to place various other nodes types into these fields, which have
to be unpacked at the other end. This makes it also weird to represent
lists of such things in the grammar, because they would have to be lists
of singleton lists, to make the unpacking work consistently. The other
problem is that keeping separate name and args fields makes it awkward
to deal with lists of functions.
Change that by dropping the objargs field and have objname, renamed to
object, be a generic Node, which can then be flexibly assigned and
managed using the normal Node mechanisms. In many cases it will still
be a List of names, in some cases it will be a string Value, for types
it will be the existing Typename, for functions it will now use the
existing ObjectWithArgs node type. Some of the more obscure object
types still use somewhat arbitrary nested lists.
Reviewed-by: Jim Nasby <Jim.Nasby@BlueTreble.com>
Reviewed-by: Michael Paquier <michael.paquier@gmail.com>
2016-11-12 18:00:00 +01:00
|
|
|
return AlterSubscriptionOwner(strVal((Value *) stmt->object),
|
2017-01-19 18:00:00 +01:00
|
|
|
newowner);
|
|
|
|
|
2013-05-29 22:58:43 +02:00
|
|
|
/* Generic cases */
|
2012-10-03 23:02:38 +02:00
|
|
|
case OBJECT_AGGREGATE:
|
|
|
|
case OBJECT_COLLATION:
|
|
|
|
case OBJECT_CONVERSION:
|
|
|
|
case OBJECT_FUNCTION:
|
|
|
|
case OBJECT_LANGUAGE:
|
|
|
|
case OBJECT_LARGEOBJECT:
|
|
|
|
case OBJECT_OPERATOR:
|
|
|
|
case OBJECT_OPCLASS:
|
|
|
|
case OBJECT_OPFAMILY:
|
2017-11-30 14:46:13 +01:00
|
|
|
case OBJECT_PROCEDURE:
|
|
|
|
case OBJECT_ROUTINE:
|
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
|
|
|
case OBJECT_STATISTIC_EXT:
|
2012-10-03 23:02:38 +02:00
|
|
|
case OBJECT_TABLESPACE:
|
|
|
|
case OBJECT_TSDICTIONARY:
|
|
|
|
case OBJECT_TSCONFIGURATION:
|
|
|
|
{
|
|
|
|
Relation catalog;
|
|
|
|
Relation relation;
|
|
|
|
Oid classId;
|
2013-05-29 22:58:43 +02:00
|
|
|
ObjectAddress address;
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
address = get_object_address(stmt->objectType,
|
|
|
|
stmt->object,
|
|
|
|
&relation,
|
|
|
|
AccessExclusiveLock,
|
|
|
|
false);
|
|
|
|
Assert(relation == NULL);
|
|
|
|
classId = address.classId;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX - get_object_address returns Oid of pg_largeobject
|
|
|
|
* catalog for OBJECT_LARGEOBJECT because of historical
|
|
|
|
* reasons. Fix up it here.
|
|
|
|
*/
|
|
|
|
if (classId == LargeObjectRelationId)
|
|
|
|
classId = LargeObjectMetadataRelationId;
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
catalog = table_open(classId, RowExclusiveLock);
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
AlterObjectOwner_internal(catalog, address.objectId, newowner);
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(catalog, RowExclusiveLock);
|
2012-12-24 00:25:03 +01:00
|
|
|
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
return address;
|
2012-10-03 23:02:38 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2004-06-25 23:55:59 +02:00
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized AlterOwnerStmt type: %d",
|
|
|
|
(int) stmt->objectType);
|
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
|
|
|
return InvalidObjectAddress; /* keep compiler happy */
|
2004-06-25 23:55:59 +02:00
|
|
|
}
|
|
|
|
}
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Generic function to change the ownership of a given object, for simple
|
|
|
|
* cases (won't work for tables, nor other cases where we need to do more than
|
|
|
|
* change the ownership column of a single catalog entry).
|
|
|
|
*
|
|
|
|
* rel: catalog relation containing object (RowExclusiveLock'd by caller)
|
|
|
|
* objectId: OID of object to change the ownership of
|
|
|
|
* new_ownerId: OID of new object owner
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
|
|
|
|
{
|
|
|
|
Oid classId = RelationGetRelid(rel);
|
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
|
|
|
AttrNumber Anum_oid = get_object_attnum_oid(classId);
|
2012-10-03 23:02:38 +02:00
|
|
|
AttrNumber Anum_owner = get_object_attnum_owner(classId);
|
|
|
|
AttrNumber Anum_namespace = get_object_attnum_namespace(classId);
|
|
|
|
AttrNumber Anum_acl = get_object_attnum_acl(classId);
|
|
|
|
AttrNumber Anum_name = get_object_attnum_name(classId);
|
|
|
|
HeapTuple oldtup;
|
|
|
|
Datum datum;
|
|
|
|
bool isnull;
|
|
|
|
Oid old_ownerId;
|
|
|
|
Oid namespaceId = InvalidOid;
|
|
|
|
|
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
|
|
|
oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
|
2012-10-03 23:02:38 +02:00
|
|
|
if (oldtup == NULL)
|
|
|
|
elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
|
|
|
|
objectId, RelationGetRelationName(rel));
|
|
|
|
|
|
|
|
datum = heap_getattr(oldtup, Anum_owner,
|
|
|
|
RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
|
|
|
old_ownerId = DatumGetObjectId(datum);
|
|
|
|
|
|
|
|
if (Anum_namespace != InvalidAttrNumber)
|
|
|
|
{
|
|
|
|
datum = heap_getattr(oldtup, Anum_namespace,
|
|
|
|
RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
|
|
|
namespaceId = DatumGetObjectId(datum);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (old_ownerId != new_ownerId)
|
|
|
|
{
|
|
|
|
AttrNumber nattrs;
|
|
|
|
HeapTuple newtup;
|
|
|
|
Datum *values;
|
|
|
|
bool *nulls;
|
|
|
|
bool *replaces;
|
|
|
|
|
|
|
|
/* Superusers can bypass permission checks */
|
|
|
|
if (!superuser())
|
|
|
|
{
|
|
|
|
/* must be owner */
|
|
|
|
if (!has_privs_of_role(GetUserId(), old_ownerId))
|
|
|
|
{
|
2013-05-29 22:58:43 +02:00
|
|
|
char *objname;
|
|
|
|
char namebuf[NAMEDATALEN];
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
if (Anum_name != InvalidAttrNumber)
|
|
|
|
{
|
|
|
|
datum = heap_getattr(oldtup, Anum_name,
|
|
|
|
RelationGetDescr(rel), &isnull);
|
|
|
|
Assert(!isnull);
|
|
|
|
objname = NameStr(*DatumGetName(datum));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
|
|
|
snprintf(namebuf, sizeof(namebuf), "%u", objectId);
|
2012-10-03 23:02:38 +02:00
|
|
|
objname = namebuf;
|
|
|
|
}
|
2019-11-05 19:40:37 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, get_object_type(classId, objectId),
|
|
|
|
objname);
|
2012-10-03 23:02:38 +02:00
|
|
|
}
|
|
|
|
/* Must be able to become new owner */
|
|
|
|
check_is_member_of_role(GetUserId(), new_ownerId);
|
|
|
|
|
|
|
|
/* New owner must have CREATE privilege on namespace */
|
|
|
|
if (OidIsValid(namespaceId))
|
|
|
|
{
|
2013-05-29 22:58:43 +02:00
|
|
|
AclResult aclresult;
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
aclresult = pg_namespace_aclcheck(namespaceId, new_ownerId,
|
|
|
|
ACL_CREATE);
|
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_SCHEMA,
|
2012-10-03 23:02:38 +02:00
|
|
|
get_namespace_name(namespaceId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Build a modified tuple */
|
|
|
|
nattrs = RelationGetNumberOfAttributes(rel);
|
|
|
|
values = palloc0(nattrs * sizeof(Datum));
|
|
|
|
nulls = palloc0(nattrs * sizeof(bool));
|
|
|
|
replaces = palloc0(nattrs * sizeof(bool));
|
|
|
|
values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId);
|
|
|
|
replaces[Anum_owner - 1] = true;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the modified ACL for the new owner. This is only
|
|
|
|
* necessary when the ACL is non-null.
|
|
|
|
*/
|
|
|
|
if (Anum_acl != InvalidAttrNumber)
|
|
|
|
{
|
|
|
|
datum = heap_getattr(oldtup,
|
|
|
|
Anum_acl, RelationGetDescr(rel), &isnull);
|
|
|
|
if (!isnull)
|
|
|
|
{
|
2013-05-29 22:58:43 +02:00
|
|
|
Acl *newAcl;
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
newAcl = aclnewowner(DatumGetAclP(datum),
|
|
|
|
old_ownerId, new_ownerId);
|
|
|
|
values[Anum_acl - 1] = PointerGetDatum(newAcl);
|
|
|
|
replaces[Anum_acl - 1] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
newtup = heap_modify_tuple(oldtup, RelationGetDescr(rel),
|
|
|
|
values, nulls, replaces);
|
|
|
|
|
|
|
|
/* Perform actual update */
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &newtup->t_self, newtup);
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
/* Update owner dependency reference */
|
|
|
|
if (classId == LargeObjectMetadataRelationId)
|
|
|
|
classId = LargeObjectRelationId;
|
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
|
|
|
changeDependencyOnOwner(classId, objectId, new_ownerId);
|
2012-10-03 23:02:38 +02:00
|
|
|
|
|
|
|
/* Release memory */
|
|
|
|
pfree(values);
|
|
|
|
pfree(nulls);
|
|
|
|
pfree(replaces);
|
|
|
|
}
|
2013-03-18 03:55:14 +01:00
|
|
|
|
|
|
|
InvokeObjectPostAlterHook(classId, objectId, 0);
|
2012-10-03 23:02:38 +02:00
|
|
|
}
|