2008-12-19 17:25:19 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* foreigncmds.c
|
|
|
|
* foreign-data wrapper/server creation/manipulation commands
|
|
|
|
*
|
2023-01-02 21:00:37 +01:00
|
|
|
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
|
2008-12-19 17:25:19 +01:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/backend/commands/foreigncmds.c
|
2008-12-19 17:25:19 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
2012-08-30 22:15:44 +02:00
|
|
|
#include "access/htup_details.h"
|
2008-12-19 17:25:19 +01:00
|
|
|
#include "access/reloptions.h"
|
2019-01-21 19:18:20 +01:00
|
|
|
#include "access/table.h"
|
2014-07-10 21:01:31 +02:00
|
|
|
#include "access/xact.h"
|
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
|
|
|
#include "catalog/catalog.h"
|
2008-12-19 17:25:19 +01:00
|
|
|
#include "catalog/dependency.h"
|
|
|
|
#include "catalog/indexing.h"
|
2010-11-25 17:48:49 +01:00
|
|
|
#include "catalog/objectaccess.h"
|
2008-12-19 17:25:19 +01:00
|
|
|
#include "catalog/pg_foreign_data_wrapper.h"
|
|
|
|
#include "catalog/pg_foreign_server.h"
|
2011-01-02 05:48:11 +01:00
|
|
|
#include "catalog/pg_foreign_table.h"
|
2009-02-24 11:06:36 +01:00
|
|
|
#include "catalog/pg_proc.h"
|
2008-12-19 17:25:19 +01:00
|
|
|
#include "catalog/pg_type.h"
|
|
|
|
#include "catalog/pg_user_mapping.h"
|
|
|
|
#include "commands/defrem.h"
|
2014-07-10 21:01:31 +02:00
|
|
|
#include "foreign/fdwapi.h"
|
2008-12-19 17:25:19 +01:00
|
|
|
#include "foreign/foreign.h"
|
|
|
|
#include "miscadmin.h"
|
2009-02-24 11:06:36 +01:00
|
|
|
#include "parser/parse_func.h"
|
2014-07-10 21:01:31 +02:00
|
|
|
#include "tcop/utility.h"
|
2008-12-19 17:25:19 +01:00
|
|
|
#include "utils/acl.h"
|
|
|
|
#include "utils/builtins.h"
|
|
|
|
#include "utils/lsyscache.h"
|
|
|
|
#include "utils/rel.h"
|
|
|
|
#include "utils/syscache.h"
|
|
|
|
|
|
|
|
|
2014-07-10 21:01:31 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
char *tablename;
|
|
|
|
char *cmd;
|
|
|
|
} import_error_callback_arg;
|
|
|
|
|
|
|
|
/* Internal functions */
|
|
|
|
static void import_error_callback(void *arg);
|
|
|
|
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
/*
|
|
|
|
* Convert a DefElem list to the text array format that is used in
|
2013-10-28 15:28:35 +01:00
|
|
|
* pg_foreign_data_wrapper, pg_foreign_server, pg_user_mapping, and
|
|
|
|
* pg_foreign_table.
|
|
|
|
*
|
2008-12-20 16:51:28 +01:00
|
|
|
* Returns the array in the form of a Datum, or PointerGetDatum(NULL)
|
|
|
|
* if the list is empty.
|
2008-12-19 17:25:19 +01:00
|
|
|
*
|
|
|
|
* Note: The array is usually stored to database without further
|
|
|
|
* processing, hence any validation should be done before this
|
|
|
|
* conversion.
|
|
|
|
*/
|
|
|
|
static Datum
|
|
|
|
optionListToArray(List *options)
|
|
|
|
{
|
|
|
|
ArrayBuildState *astate = NULL;
|
|
|
|
ListCell *cell;
|
|
|
|
|
2008-12-20 16:51:28 +01:00
|
|
|
foreach(cell, options)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
|
|
|
DefElem *def = lfirst(cell);
|
2008-12-20 16:51:28 +01:00
|
|
|
const char *value;
|
2008-12-19 17:25:19 +01:00
|
|
|
Size len;
|
2008-12-20 16:51:28 +01:00
|
|
|
text *t;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
value = defGetString(def);
|
|
|
|
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
|
|
|
|
t = palloc(len + 1);
|
|
|
|
SET_VARSIZE(t, len);
|
|
|
|
sprintf(VARDATA(t), "%s=%s", def->defname, value);
|
|
|
|
|
|
|
|
astate = accumArrayResult(astate, PointerGetDatum(t),
|
|
|
|
false, TEXTOID,
|
|
|
|
CurrentMemoryContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (astate)
|
|
|
|
return makeArrayResult(astate, CurrentMemoryContext);
|
|
|
|
|
|
|
|
return PointerGetDatum(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2009-04-04 23:12:31 +02:00
|
|
|
* Transform a list of DefElem into text array format. This is substantially
|
|
|
|
* the same thing as optionListToArray(), except we recognize SET/ADD/DROP
|
|
|
|
* actions for modifying an existing list of options, which is passed in
|
|
|
|
* Datum form as oldOptions. Also, if fdwvalidator isn't InvalidOid
|
|
|
|
* it specifies a validator function to call on the result.
|
2008-12-19 17:25:19 +01:00
|
|
|
*
|
2008-12-20 16:51:28 +01:00
|
|
|
* Returns the array in the form of a Datum, or PointerGetDatum(NULL)
|
|
|
|
* if the list is empty.
|
|
|
|
*
|
2013-10-28 15:28:35 +01:00
|
|
|
* This is used by CREATE/ALTER of FOREIGN DATA WRAPPER/SERVER/USER MAPPING/
|
|
|
|
* FOREIGN TABLE.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
2011-01-02 05:48:11 +01:00
|
|
|
Datum
|
2009-12-23 13:23:59 +01:00
|
|
|
transformGenericOptions(Oid catalogId,
|
|
|
|
Datum oldOptions,
|
2009-04-04 23:12:31 +02:00
|
|
|
List *options,
|
2009-02-24 11:06:36 +01:00
|
|
|
Oid fdwvalidator)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
|
|
|
List *resultOptions = untransformRelOptions(oldOptions);
|
|
|
|
ListCell *optcell;
|
2009-02-24 11:06:36 +01:00
|
|
|
Datum result;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2009-04-04 23:12:31 +02:00
|
|
|
foreach(optcell, options)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
2009-04-04 23:12:31 +02:00
|
|
|
DefElem *od = lfirst(optcell);
|
|
|
|
ListCell *cell;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Find the element in resultOptions. We need this for validation in
|
Represent Lists as expansible arrays, not chains of cons-cells.
Originally, Postgres Lists were a more or less exact reimplementation of
Lisp lists, which consist of chains of separately-allocated cons cells,
each having a value and a next-cell link. We'd hacked that once before
(commit d0b4399d8) to add a separate List header, but the data was still
in cons cells. That makes some operations -- notably list_nth() -- O(N),
and it's bulky because of the next-cell pointers and per-cell palloc
overhead, and it's very cache-unfriendly if the cons cells end up
scattered around rather than being adjacent.
In this rewrite, we still have List headers, but the data is in a
resizable array of values, with no next-cell links. Now we need at
most two palloc's per List, and often only one, since we can allocate
some values in the same palloc call as the List header. (Of course,
extending an existing List may require repalloc's to enlarge the array.
But this involves just O(log N) allocations not O(N).)
Of course this is not without downsides. The key difficulty is that
addition or deletion of a list entry may now cause other entries to
move, which it did not before.
For example, that breaks foreach() and sister macros, which historically
used a pointer to the current cons-cell as loop state. We can repair
those macros transparently by making their actual loop state be an
integer list index; the exposed "ListCell *" pointer is no longer state
carried across loop iterations, but is just a derived value. (In
practice, modern compilers can optimize things back to having just one
loop state value, at least for simple cases with inline loop bodies.)
In principle, this is a semantics change for cases where the loop body
inserts or deletes list entries ahead of the current loop index; but
I found no such cases in the Postgres code.
The change is not at all transparent for code that doesn't use foreach()
but chases lists "by hand" using lnext(). The largest share of such
code in the backend is in loops that were maintaining "prev" and "next"
variables in addition to the current-cell pointer, in order to delete
list cells efficiently using list_delete_cell(). However, we no longer
need a previous-cell pointer to delete a list cell efficiently. Keeping
a next-cell pointer doesn't work, as explained above, but we can improve
matters by changing such code to use a regular foreach() loop and then
using the new macro foreach_delete_current() to delete the current cell.
(This macro knows how to update the associated foreach loop's state so
that no cells will be missed in the traversal.)
There remains a nontrivial risk of code assuming that a ListCell *
pointer will remain good over an operation that could now move the list
contents. To help catch such errors, list.c can be compiled with a new
define symbol DEBUG_LIST_MEMORY_USAGE that forcibly moves list contents
whenever that could possibly happen. This makes list operations
significantly more expensive so it's not normally turned on (though it
is on by default if USE_VALGRIND is on).
There are two notable API differences from the previous code:
* lnext() now requires the List's header pointer in addition to the
current cell's address.
* list_delete_cell() no longer requires a previous-cell argument.
These changes are somewhat unfortunate, but on the other hand code using
either function needs inspection to see if it is assuming anything
it shouldn't, so it's not all bad.
Programmers should be aware of these significant performance changes:
* list_nth() and related functions are now O(1); so there's no
major access-speed difference between a list and an array.
* Inserting or deleting a list element now takes time proportional to
the distance to the end of the list, due to moving the array elements.
(However, it typically *doesn't* require palloc or pfree, so except in
long lists it's probably still faster than before.) Notably, lcons()
used to be about the same cost as lappend(), but that's no longer true
if the list is long. Code that uses lcons() and list_delete_first()
to maintain a stack might usefully be rewritten to push and pop at the
end of the list rather than the beginning.
* There are now list_insert_nth...() and list_delete_nth...() functions
that add or remove a list cell identified by index. These have the
data-movement penalty explained above, but there's no search penalty.
* list_concat() and variants now copy the second list's data into
storage belonging to the first list, so there is no longer any
sharing of cells between the input lists. The second argument is
now declared "const List *" to reflect that it isn't changed.
This patch just does the minimum needed to get the new implementation
in place and fix bugs exposed by the regression tests. As suggested
by the foregoing, there's a fair amount of followup work remaining to
do.
Also, the ENABLE_LIST_COMPAT macros are finally removed in this
commit. Code using those should have been gone a dozen years ago.
Patch by me; thanks to David Rowley, Jesper Pedersen, and others
for review.
Discussion: https://postgr.es/m/11587.1550975080@sss.pgh.pa.us
2019-07-15 19:41:58 +02:00
|
|
|
* all cases.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
|
|
|
foreach(cell, resultOptions)
|
|
|
|
{
|
|
|
|
DefElem *def = lfirst(cell);
|
|
|
|
|
2009-04-04 23:12:31 +02:00
|
|
|
if (strcmp(def->defname, od->defname) == 0)
|
2008-12-19 17:25:19 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* It is possible to perform multiple SET/DROP actions on the same
|
|
|
|
* option. The standard permits this, as long as the options to be
|
2009-04-04 23:12:31 +02:00
|
|
|
* added are unique. Note that an unspecified action is taken to be
|
|
|
|
* ADD.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
2009-04-04 23:12:31 +02:00
|
|
|
switch (od->defaction)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
2009-04-04 23:12:31 +02:00
|
|
|
case DEFELEM_DROP:
|
2008-12-19 17:25:19 +01:00
|
|
|
if (!cell)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("option \"%s\" not found",
|
2009-04-04 23:12:31 +02:00
|
|
|
od->defname)));
|
Represent Lists as expansible arrays, not chains of cons-cells.
Originally, Postgres Lists were a more or less exact reimplementation of
Lisp lists, which consist of chains of separately-allocated cons cells,
each having a value and a next-cell link. We'd hacked that once before
(commit d0b4399d8) to add a separate List header, but the data was still
in cons cells. That makes some operations -- notably list_nth() -- O(N),
and it's bulky because of the next-cell pointers and per-cell palloc
overhead, and it's very cache-unfriendly if the cons cells end up
scattered around rather than being adjacent.
In this rewrite, we still have List headers, but the data is in a
resizable array of values, with no next-cell links. Now we need at
most two palloc's per List, and often only one, since we can allocate
some values in the same palloc call as the List header. (Of course,
extending an existing List may require repalloc's to enlarge the array.
But this involves just O(log N) allocations not O(N).)
Of course this is not without downsides. The key difficulty is that
addition or deletion of a list entry may now cause other entries to
move, which it did not before.
For example, that breaks foreach() and sister macros, which historically
used a pointer to the current cons-cell as loop state. We can repair
those macros transparently by making their actual loop state be an
integer list index; the exposed "ListCell *" pointer is no longer state
carried across loop iterations, but is just a derived value. (In
practice, modern compilers can optimize things back to having just one
loop state value, at least for simple cases with inline loop bodies.)
In principle, this is a semantics change for cases where the loop body
inserts or deletes list entries ahead of the current loop index; but
I found no such cases in the Postgres code.
The change is not at all transparent for code that doesn't use foreach()
but chases lists "by hand" using lnext(). The largest share of such
code in the backend is in loops that were maintaining "prev" and "next"
variables in addition to the current-cell pointer, in order to delete
list cells efficiently using list_delete_cell(). However, we no longer
need a previous-cell pointer to delete a list cell efficiently. Keeping
a next-cell pointer doesn't work, as explained above, but we can improve
matters by changing such code to use a regular foreach() loop and then
using the new macro foreach_delete_current() to delete the current cell.
(This macro knows how to update the associated foreach loop's state so
that no cells will be missed in the traversal.)
There remains a nontrivial risk of code assuming that a ListCell *
pointer will remain good over an operation that could now move the list
contents. To help catch such errors, list.c can be compiled with a new
define symbol DEBUG_LIST_MEMORY_USAGE that forcibly moves list contents
whenever that could possibly happen. This makes list operations
significantly more expensive so it's not normally turned on (though it
is on by default if USE_VALGRIND is on).
There are two notable API differences from the previous code:
* lnext() now requires the List's header pointer in addition to the
current cell's address.
* list_delete_cell() no longer requires a previous-cell argument.
These changes are somewhat unfortunate, but on the other hand code using
either function needs inspection to see if it is assuming anything
it shouldn't, so it's not all bad.
Programmers should be aware of these significant performance changes:
* list_nth() and related functions are now O(1); so there's no
major access-speed difference between a list and an array.
* Inserting or deleting a list element now takes time proportional to
the distance to the end of the list, due to moving the array elements.
(However, it typically *doesn't* require palloc or pfree, so except in
long lists it's probably still faster than before.) Notably, lcons()
used to be about the same cost as lappend(), but that's no longer true
if the list is long. Code that uses lcons() and list_delete_first()
to maintain a stack might usefully be rewritten to push and pop at the
end of the list rather than the beginning.
* There are now list_insert_nth...() and list_delete_nth...() functions
that add or remove a list cell identified by index. These have the
data-movement penalty explained above, but there's no search penalty.
* list_concat() and variants now copy the second list's data into
storage belonging to the first list, so there is no longer any
sharing of cells between the input lists. The second argument is
now declared "const List *" to reflect that it isn't changed.
This patch just does the minimum needed to get the new implementation
in place and fix bugs exposed by the regression tests. As suggested
by the foregoing, there's a fair amount of followup work remaining to
do.
Also, the ENABLE_LIST_COMPAT macros are finally removed in this
commit. Code using those should have been gone a dozen years ago.
Patch by me; thanks to David Rowley, Jesper Pedersen, and others
for review.
Discussion: https://postgr.es/m/11587.1550975080@sss.pgh.pa.us
2019-07-15 19:41:58 +02:00
|
|
|
resultOptions = list_delete_cell(resultOptions, cell);
|
2008-12-19 17:25:19 +01:00
|
|
|
break;
|
|
|
|
|
2009-04-04 23:12:31 +02:00
|
|
|
case DEFELEM_SET:
|
2008-12-19 17:25:19 +01:00
|
|
|
if (!cell)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("option \"%s\" not found",
|
2009-04-04 23:12:31 +02:00
|
|
|
od->defname)));
|
|
|
|
lfirst(cell) = od;
|
2008-12-19 17:25:19 +01:00
|
|
|
break;
|
|
|
|
|
2009-04-04 23:12:31 +02:00
|
|
|
case DEFELEM_ADD:
|
|
|
|
case DEFELEM_UNSPEC:
|
2008-12-19 17:25:19 +01:00
|
|
|
if (cell)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("option \"%s\" provided more than once",
|
2009-04-04 23:12:31 +02:00
|
|
|
od->defname)));
|
|
|
|
resultOptions = lappend(resultOptions, od);
|
2008-12-19 17:25:19 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized action %d on option \"%s\"",
|
2009-04-04 23:12:31 +02:00
|
|
|
(int) od->defaction, od->defname);
|
2008-12-19 17:25:19 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-24 11:06:36 +01:00
|
|
|
result = optionListToArray(resultOptions);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2011-07-06 00:21:12 +02:00
|
|
|
if (OidIsValid(fdwvalidator))
|
|
|
|
{
|
|
|
|
Datum valarg = result;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pass a null options list as an empty array, so that validators
|
|
|
|
* don't have to be declared non-strict to handle the case.
|
|
|
|
*/
|
|
|
|
if (DatumGetPointer(valarg) == NULL)
|
|
|
|
valarg = PointerGetDatum(construct_empty_array(TEXTOID));
|
|
|
|
OidFunctionCall2(fdwvalidator, valarg, ObjectIdGetDatum(catalogId));
|
|
|
|
}
|
2009-02-24 11:06:36 +01:00
|
|
|
|
|
|
|
return result;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2012-02-21 21:58:02 +01:00
|
|
|
* Internal workhorse for changing a data wrapper's owner.
|
2008-12-19 17:25:19 +01:00
|
|
|
*
|
|
|
|
* Allow this only for superusers; also the new owner must be a
|
|
|
|
* superuser.
|
|
|
|
*/
|
2012-02-21 21:58:02 +01:00
|
|
|
static void
|
|
|
|
AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
|
|
|
Form_pg_foreign_data_wrapper form;
|
2015-01-22 18:36:34 +01:00
|
|
|
Datum repl_val[Natts_pg_foreign_data_wrapper];
|
|
|
|
bool repl_null[Natts_pg_foreign_data_wrapper];
|
|
|
|
bool repl_repl[Natts_pg_foreign_data_wrapper];
|
|
|
|
Acl *newAcl;
|
|
|
|
Datum aclDatum;
|
|
|
|
bool isNull;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2012-02-21 21:58:02 +01:00
|
|
|
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
/* Must be a superuser to change a FDW owner */
|
|
|
|
if (!superuser())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
|
2012-02-21 21:58:02 +01:00
|
|
|
NameStr(form->fdwname)),
|
2008-12-19 17:25:19 +01:00
|
|
|
errhint("Must be superuser to change owner of a foreign-data wrapper.")));
|
|
|
|
|
|
|
|
/* New owner must also be a superuser */
|
|
|
|
if (!superuser_arg(newOwnerId))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("permission denied to change owner of foreign-data wrapper \"%s\"",
|
2012-02-21 21:58:02 +01:00
|
|
|
NameStr(form->fdwname)),
|
2008-12-19 17:25:19 +01:00
|
|
|
errhint("The owner of a foreign-data wrapper must be a superuser.")));
|
|
|
|
|
|
|
|
if (form->fdwowner != newOwnerId)
|
|
|
|
{
|
2015-01-22 18:36:34 +01:00
|
|
|
memset(repl_null, false, sizeof(repl_null));
|
|
|
|
memset(repl_repl, false, sizeof(repl_repl));
|
|
|
|
|
|
|
|
repl_repl[Anum_pg_foreign_data_wrapper_fdwowner - 1] = true;
|
|
|
|
repl_val[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(newOwnerId);
|
|
|
|
|
|
|
|
aclDatum = heap_getattr(tup,
|
|
|
|
Anum_pg_foreign_data_wrapper_fdwacl,
|
|
|
|
RelationGetDescr(rel),
|
|
|
|
&isNull);
|
|
|
|
/* Null ACLs do not require changes */
|
|
|
|
if (!isNull)
|
|
|
|
{
|
|
|
|
newAcl = aclnewowner(DatumGetAclP(aclDatum),
|
|
|
|
form->fdwowner, newOwnerId);
|
|
|
|
repl_repl[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
|
|
|
|
repl_val[Anum_pg_foreign_data_wrapper_fdwacl - 1] = PointerGetDatum(newAcl);
|
|
|
|
}
|
|
|
|
|
|
|
|
tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null,
|
|
|
|
repl_repl);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &tup->t_self, tup);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* Update owner dependency reference */
|
|
|
|
changeDependencyOnOwner(ForeignDataWrapperRelationId,
|
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
|
|
|
form->oid,
|
2008-12-19 17:25:19 +01:00
|
|
|
newOwnerId);
|
|
|
|
}
|
2013-03-18 03:55:14 +01:00
|
|
|
|
|
|
|
InvokeObjectPostAlterHook(ForeignDataWrapperRelationId,
|
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
|
|
|
form->oid, 0);
|
2012-02-21 21:58:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change foreign-data wrapper owner -- by name
|
|
|
|
*
|
|
|
|
* Note restrictions in the "_internal" function, above.
|
|
|
|
*/
|
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
|
2012-02-21 21:58:02 +01:00
|
|
|
AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
|
|
|
|
{
|
2012-12-24 00:25:03 +01:00
|
|
|
Oid fdwId;
|
2012-02-21 21:58:02 +01:00
|
|
|
HeapTuple tup;
|
|
|
|
Relation rel;
|
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;
|
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
|
|
|
Form_pg_foreign_data_wrapper form;
|
|
|
|
|
2012-02-21 21:58:02 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock);
|
2012-02-21 21:58:02 +01:00
|
|
|
|
|
|
|
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME, CStringGetDatum(name));
|
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tup))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("foreign-data wrapper \"%s\" does not exist", name)));
|
|
|
|
|
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
|
|
|
form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
|
|
|
|
fdwId = form->oid;
|
2012-12-24 00:25:03 +01:00
|
|
|
|
2012-02-21 21:58:02 +01:00
|
|
|
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
|
2008-12-19 17:25:19 +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
|
|
|
ObjectAddressSet(address, ForeignDataWrapperRelationId, fdwId);
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
heap_freetuple(tup);
|
2011-02-19 06:06:18 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, 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;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-02-21 21:58:02 +01:00
|
|
|
* Change foreign-data wrapper owner -- by OID
|
|
|
|
*
|
|
|
|
* Note restrictions in the "_internal" function, above.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
|
|
|
void
|
2012-02-21 21:58:02 +01:00
|
|
|
AlterForeignDataWrapperOwner_oid(Oid fwdId, Oid newOwnerId)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
|
|
|
HeapTuple tup;
|
|
|
|
Relation rel;
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2012-02-21 21:58:02 +01:00
|
|
|
tup = SearchSysCacheCopy1(FOREIGNDATAWRAPPEROID, ObjectIdGetDatum(fwdId));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tup))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2012-02-23 11:51:33 +01:00
|
|
|
errmsg("foreign-data wrapper with OID %u does not exist", fwdId)));
|
2012-02-21 21:58:02 +01:00
|
|
|
|
|
|
|
AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
|
|
|
|
|
|
|
|
heap_freetuple(tup);
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-02-21 21:58:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Internal workhorse for changing a foreign server's owner
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
|
|
|
|
{
|
|
|
|
Form_pg_foreign_server form;
|
2015-01-22 18:36:34 +01:00
|
|
|
Datum repl_val[Natts_pg_foreign_server];
|
|
|
|
bool repl_null[Natts_pg_foreign_server];
|
|
|
|
bool repl_repl[Natts_pg_foreign_server];
|
|
|
|
Acl *newAcl;
|
|
|
|
Datum aclDatum;
|
|
|
|
bool isNull;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
form = (Form_pg_foreign_server) GETSTRUCT(tup);
|
|
|
|
|
|
|
|
if (form->srvowner != newOwnerId)
|
|
|
|
{
|
|
|
|
/* Superusers can always do it */
|
|
|
|
if (!superuser())
|
|
|
|
{
|
2012-02-21 21:58:02 +01:00
|
|
|
Oid srvId;
|
|
|
|
AclResult aclresult;
|
|
|
|
|
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
|
|
|
srvId = form->oid;
|
2012-02-21 21:58:02 +01:00
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
/* Must be owner */
|
2022-11-13 08:11:17 +01:00
|
|
|
if (!object_ownercheck(ForeignServerRelationId, srvId, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FOREIGN_SERVER,
|
2012-02-21 21:58:02 +01:00
|
|
|
NameStr(form->srvname));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* Must be able to become new owner */
|
Add a SET option to the GRANT command.
Similar to how the INHERIT option controls whether or not the
permissions of the granted role are automatically available to the
grantee, the new SET permission controls whether or not the grantee
may use the SET ROLE command to assume the privileges of the granted
role.
In addition, the new SET permission controls whether or not it
is possible to transfer ownership of objects to the target role
or to create new objects owned by the target role using commands
such as CREATE DATABASE .. OWNER. We could alternatively have made
this controlled by the INHERIT option, or allow it when either
option is given. An advantage of this approach is that if you
are granted a predefined role with INHERIT TRUE, SET FALSE, you
can't go and create objects owned by that role.
The underlying theory here is that the ability to create objects
as a target role is not a privilege per se, and thus does not
depend on whether you inherit the target role's privileges. However,
it's surely something you could do anyway if you could SET ROLE
to the target role, and thus making it contingent on whether you
have that ability is reasonable.
Design review by Nathan Bossat, Wolfgang Walther, Jeff Davis,
Peter Eisentraut, and Stephen Frost.
Discussion: http://postgr.es/m/CA+Tgmob+zDSRS6JXYrgq0NWdzCXuTNzT5eK54Dn2hhgt17nm8A@mail.gmail.com
2022-11-18 18:32:50 +01:00
|
|
|
check_can_set_role(GetUserId(), newOwnerId);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* New owner must have USAGE privilege on foreign-data wrapper */
|
2022-11-13 08:11:17 +01:00
|
|
|
aclresult = object_aclcheck(ForeignDataWrapperRelationId, form->srvfdw, newOwnerId, ACL_USAGE);
|
2008-12-19 17:25:19 +01:00
|
|
|
if (aclresult != ACLCHECK_OK)
|
|
|
|
{
|
|
|
|
ForeignDataWrapper *fdw = GetForeignDataWrapper(form->srvfdw);
|
|
|
|
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_FDW, fdw->fdwname);
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-22 18:36:34 +01:00
|
|
|
memset(repl_null, false, sizeof(repl_null));
|
|
|
|
memset(repl_repl, false, sizeof(repl_repl));
|
2015-01-22 22:57:16 +01:00
|
|
|
|
2015-01-22 18:36:34 +01:00
|
|
|
repl_repl[Anum_pg_foreign_server_srvowner - 1] = true;
|
|
|
|
repl_val[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(newOwnerId);
|
2015-01-22 22:57:16 +01:00
|
|
|
|
2015-01-22 18:36:34 +01:00
|
|
|
aclDatum = heap_getattr(tup,
|
|
|
|
Anum_pg_foreign_server_srvacl,
|
|
|
|
RelationGetDescr(rel),
|
|
|
|
&isNull);
|
|
|
|
/* Null ACLs do not require changes */
|
|
|
|
if (!isNull)
|
|
|
|
{
|
|
|
|
newAcl = aclnewowner(DatumGetAclP(aclDatum),
|
|
|
|
form->srvowner, newOwnerId);
|
|
|
|
repl_repl[Anum_pg_foreign_server_srvacl - 1] = true;
|
|
|
|
repl_val[Anum_pg_foreign_server_srvacl - 1] = PointerGetDatum(newAcl);
|
|
|
|
}
|
2015-01-22 22:57:16 +01:00
|
|
|
|
2015-01-22 18:36:34 +01:00
|
|
|
tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null,
|
|
|
|
repl_repl);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &tup->t_self, tup);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* Update owner dependency reference */
|
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(ForeignServerRelationId, form->oid,
|
2008-12-19 17:25:19 +01:00
|
|
|
newOwnerId);
|
|
|
|
}
|
2013-03-18 03:55:14 +01:00
|
|
|
|
|
|
|
InvokeObjectPostAlterHook(ForeignServerRelationId,
|
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
|
|
|
form->oid, 0);
|
2012-02-21 21:58:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Change foreign server owner -- by name
|
|
|
|
*/
|
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
|
2012-02-21 21:58:02 +01:00
|
|
|
AlterForeignServerOwner(const char *name, Oid newOwnerId)
|
|
|
|
{
|
2012-12-24 00:25:03 +01:00
|
|
|
Oid servOid;
|
2012-02-21 21:58:02 +01:00
|
|
|
HeapTuple tup;
|
|
|
|
Relation rel;
|
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;
|
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
|
|
|
Form_pg_foreign_server form;
|
2012-02-21 21:58:02 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignServerRelationId, RowExclusiveLock);
|
2012-02-21 21:58:02 +01:00
|
|
|
|
|
|
|
tup = SearchSysCacheCopy1(FOREIGNSERVERNAME, CStringGetDatum(name));
|
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tup))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("server \"%s\" does not exist", name)));
|
|
|
|
|
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
|
|
|
form = (Form_pg_foreign_server) GETSTRUCT(tup);
|
|
|
|
servOid = form->oid;
|
2012-12-24 00:25:03 +01:00
|
|
|
|
2012-02-21 21:58:02 +01:00
|
|
|
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
|
2008-12-19 17:25:19 +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
|
|
|
ObjectAddressSet(address, ForeignServerRelationId, servOid);
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
heap_freetuple(tup);
|
2011-02-19 06:06:18 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, 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;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
2012-02-21 21:58:02 +01:00
|
|
|
/*
|
|
|
|
* Change foreign server owner -- by OID
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
AlterForeignServerOwner_oid(Oid srvId, Oid newOwnerId)
|
|
|
|
{
|
|
|
|
HeapTuple tup;
|
|
|
|
Relation rel;
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignServerRelationId, RowExclusiveLock);
|
2012-02-21 21:58:02 +01:00
|
|
|
|
|
|
|
tup = SearchSysCacheCopy1(FOREIGNSERVEROID, ObjectIdGetDatum(srvId));
|
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tup))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2012-02-23 11:51:33 +01:00
|
|
|
errmsg("foreign server with OID %u does not exist", srvId)));
|
2012-02-21 21:58:02 +01:00
|
|
|
|
|
|
|
AlterForeignServerOwner_internal(rel, tup, newOwnerId);
|
|
|
|
|
|
|
|
heap_freetuple(tup);
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-02-21 21:58:02 +01:00
|
|
|
}
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
/*
|
|
|
|
* Convert a handler function name passed from the parser to an Oid.
|
|
|
|
*/
|
|
|
|
static Oid
|
|
|
|
lookup_fdw_handler_func(DefElem *handler)
|
|
|
|
{
|
|
|
|
Oid handlerOid;
|
|
|
|
|
|
|
|
if (handler == NULL || handler->arg == NULL)
|
|
|
|
return InvalidOid;
|
|
|
|
|
|
|
|
/* handlers have no arguments */
|
2019-11-12 21:04:46 +01:00
|
|
|
handlerOid = LookupFuncName((List *) handler->arg, 0, NULL, false);
|
2011-02-19 06:06:18 +01:00
|
|
|
|
|
|
|
/* check that handler has correct return type */
|
|
|
|
if (get_func_rettype(handlerOid) != FDW_HANDLEROID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
2016-04-01 18:35:48 +02:00
|
|
|
errmsg("function %s must return type %s",
|
2016-03-28 19:12:00 +02:00
|
|
|
NameListToString((List *) handler->arg), "fdw_handler")));
|
2011-02-19 06:06:18 +01:00
|
|
|
|
|
|
|
return handlerOid;
|
|
|
|
}
|
|
|
|
|
2009-02-24 11:06:36 +01:00
|
|
|
/*
|
|
|
|
* Convert a validator function name passed from the parser to an Oid.
|
|
|
|
*/
|
|
|
|
static Oid
|
2011-02-19 06:06:18 +01:00
|
|
|
lookup_fdw_validator_func(DefElem *validator)
|
2009-02-24 11:06:36 +01:00
|
|
|
{
|
|
|
|
Oid funcargtypes[2];
|
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
if (validator == NULL || validator->arg == NULL)
|
|
|
|
return InvalidOid;
|
|
|
|
|
|
|
|
/* validators take text[], oid */
|
2009-02-24 11:06:36 +01:00
|
|
|
funcargtypes[0] = TEXTARRAYOID;
|
|
|
|
funcargtypes[1] = OIDOID;
|
2011-02-19 06:06:18 +01:00
|
|
|
|
|
|
|
return LookupFuncName((List *) validator->arg, 2, funcargtypes, false);
|
|
|
|
/* validator's return value is ignored, so we don't check the type */
|
2009-02-24 11:06:36 +01:00
|
|
|
}
|
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
/*
|
|
|
|
* Process function options of CREATE/ALTER FDW
|
|
|
|
*/
|
|
|
|
static void
|
Improve reporting of "conflicting or redundant options" errors.
When reporting "conflicting or redundant options" errors, try to
ensure that errposition() is used, to help the user identify the
offending option.
Formerly, errposition() was invoked in less than 60% of cases. This
patch raises that to over 90%, but there remain a few places where the
ParseState is not readily available. Using errdetail() might improve
the error in such cases, but that is left as a task for the future.
Additionally, since this error is thrown from over 100 places in the
codebase, introduce a dedicated function to throw it, reducing code
duplication.
Extracted from a slightly larger patch by Vignesh C. Reviewed by
Bharath Rupireddy, Alvaro Herrera, Dilip Kumar, Hou Zhijie, Peter
Smith, Daniel Gustafsson, Julien Rouhaud and me.
Discussion: https://postgr.es/m/CALDaNm33FFSS5tVyvmkoK2cCMuDVxcui=gFrjti9ROfynqSAGA@mail.gmail.com
2021-07-15 09:49:45 +02:00
|
|
|
parse_func_options(ParseState *pstate, List *func_options,
|
2011-02-19 06:06:18 +01:00
|
|
|
bool *handler_given, Oid *fdwhandler,
|
|
|
|
bool *validator_given, Oid *fdwvalidator)
|
|
|
|
{
|
|
|
|
ListCell *cell;
|
|
|
|
|
|
|
|
*handler_given = false;
|
|
|
|
*validator_given = false;
|
|
|
|
/* return InvalidOid if not given */
|
|
|
|
*fdwhandler = InvalidOid;
|
|
|
|
*fdwvalidator = InvalidOid;
|
|
|
|
|
|
|
|
foreach(cell, func_options)
|
|
|
|
{
|
|
|
|
DefElem *def = (DefElem *) lfirst(cell);
|
|
|
|
|
|
|
|
if (strcmp(def->defname, "handler") == 0)
|
|
|
|
{
|
|
|
|
if (*handler_given)
|
Improve reporting of "conflicting or redundant options" errors.
When reporting "conflicting or redundant options" errors, try to
ensure that errposition() is used, to help the user identify the
offending option.
Formerly, errposition() was invoked in less than 60% of cases. This
patch raises that to over 90%, but there remain a few places where the
ParseState is not readily available. Using errdetail() might improve
the error in such cases, but that is left as a task for the future.
Additionally, since this error is thrown from over 100 places in the
codebase, introduce a dedicated function to throw it, reducing code
duplication.
Extracted from a slightly larger patch by Vignesh C. Reviewed by
Bharath Rupireddy, Alvaro Herrera, Dilip Kumar, Hou Zhijie, Peter
Smith, Daniel Gustafsson, Julien Rouhaud and me.
Discussion: https://postgr.es/m/CALDaNm33FFSS5tVyvmkoK2cCMuDVxcui=gFrjti9ROfynqSAGA@mail.gmail.com
2021-07-15 09:49:45 +02:00
|
|
|
errorConflictingDefElem(def, pstate);
|
2011-02-19 06:06:18 +01:00
|
|
|
*handler_given = true;
|
|
|
|
*fdwhandler = lookup_fdw_handler_func(def);
|
|
|
|
}
|
|
|
|
else if (strcmp(def->defname, "validator") == 0)
|
|
|
|
{
|
|
|
|
if (*validator_given)
|
Improve reporting of "conflicting or redundant options" errors.
When reporting "conflicting or redundant options" errors, try to
ensure that errposition() is used, to help the user identify the
offending option.
Formerly, errposition() was invoked in less than 60% of cases. This
patch raises that to over 90%, but there remain a few places where the
ParseState is not readily available. Using errdetail() might improve
the error in such cases, but that is left as a task for the future.
Additionally, since this error is thrown from over 100 places in the
codebase, introduce a dedicated function to throw it, reducing code
duplication.
Extracted from a slightly larger patch by Vignesh C. Reviewed by
Bharath Rupireddy, Alvaro Herrera, Dilip Kumar, Hou Zhijie, Peter
Smith, Daniel Gustafsson, Julien Rouhaud and me.
Discussion: https://postgr.es/m/CALDaNm33FFSS5tVyvmkoK2cCMuDVxcui=gFrjti9ROfynqSAGA@mail.gmail.com
2021-07-15 09:49:45 +02:00
|
|
|
errorConflictingDefElem(def, pstate);
|
2011-02-19 06:06:18 +01:00
|
|
|
*validator_given = true;
|
|
|
|
*fdwvalidator = lookup_fdw_validator_func(def);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
elog(ERROR, "option \"%s\" not recognized",
|
|
|
|
def->defname);
|
|
|
|
}
|
|
|
|
}
|
2009-02-24 11:06:36 +01:00
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
/*
|
|
|
|
* Create a foreign-data wrapper
|
|
|
|
*/
|
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
|
Improve reporting of "conflicting or redundant options" errors.
When reporting "conflicting or redundant options" errors, try to
ensure that errposition() is used, to help the user identify the
offending option.
Formerly, errposition() was invoked in less than 60% of cases. This
patch raises that to over 90%, but there remain a few places where the
ParseState is not readily available. Using errdetail() might improve
the error in such cases, but that is left as a task for the future.
Additionally, since this error is thrown from over 100 places in the
codebase, introduce a dedicated function to throw it, reducing code
duplication.
Extracted from a slightly larger patch by Vignesh C. Reviewed by
Bharath Rupireddy, Alvaro Herrera, Dilip Kumar, Hou Zhijie, Peter
Smith, Daniel Gustafsson, Julien Rouhaud and me.
Discussion: https://postgr.es/m/CALDaNm33FFSS5tVyvmkoK2cCMuDVxcui=gFrjti9ROfynqSAGA@mail.gmail.com
2021-07-15 09:49:45 +02:00
|
|
|
CreateForeignDataWrapper(ParseState *pstate, CreateFdwStmt *stmt)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
|
|
|
Relation rel;
|
|
|
|
Datum values[Natts_pg_foreign_data_wrapper];
|
|
|
|
bool nulls[Natts_pg_foreign_data_wrapper];
|
|
|
|
HeapTuple tuple;
|
|
|
|
Oid fdwId;
|
2011-02-19 06:06:18 +01:00
|
|
|
bool handler_given;
|
|
|
|
bool validator_given;
|
|
|
|
Oid fdwhandler;
|
2009-02-24 11:06:36 +01:00
|
|
|
Oid fdwvalidator;
|
2008-12-20 10:40:56 +01:00
|
|
|
Datum fdwoptions;
|
2008-12-19 17:25:19 +01:00
|
|
|
Oid ownerId;
|
2011-02-08 22:08:41 +01:00
|
|
|
ObjectAddress myself;
|
|
|
|
ObjectAddress referenced;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
2021-09-08 17:02:18 +02:00
|
|
|
/* Must be superuser */
|
2008-12-19 17:25:19 +01:00
|
|
|
if (!superuser())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("permission denied to create foreign-data wrapper \"%s\"",
|
|
|
|
stmt->fdwname),
|
|
|
|
errhint("Must be superuser to create a foreign-data wrapper.")));
|
|
|
|
|
|
|
|
/* For now the owner cannot be specified on create. Use effective user ID. */
|
|
|
|
ownerId = GetUserId();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that there is no other foreign-data wrapper by this name.
|
|
|
|
*/
|
|
|
|
if (GetForeignDataWrapperByName(stmt->fdwname, true) != NULL)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("foreign-data wrapper \"%s\" already exists",
|
|
|
|
stmt->fdwname)));
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Insert tuple into pg_foreign_data_wrapper.
|
|
|
|
*/
|
2008-12-20 16:51:28 +01:00
|
|
|
memset(values, 0, sizeof(values));
|
|
|
|
memset(nulls, false, sizeof(nulls));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
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
|
|
|
fdwId = GetNewOidWithIndex(rel, ForeignDataWrapperOidIndexId,
|
|
|
|
Anum_pg_foreign_data_wrapper_oid);
|
|
|
|
values[Anum_pg_foreign_data_wrapper_oid - 1] = ObjectIdGetDatum(fdwId);
|
2008-12-19 17:25:19 +01:00
|
|
|
values[Anum_pg_foreign_data_wrapper_fdwname - 1] =
|
|
|
|
DirectFunctionCall1(namein, CStringGetDatum(stmt->fdwname));
|
|
|
|
values[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(ownerId);
|
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
/* Lookup handler and validator functions, if given */
|
Improve reporting of "conflicting or redundant options" errors.
When reporting "conflicting or redundant options" errors, try to
ensure that errposition() is used, to help the user identify the
offending option.
Formerly, errposition() was invoked in less than 60% of cases. This
patch raises that to over 90%, but there remain a few places where the
ParseState is not readily available. Using errdetail() might improve
the error in such cases, but that is left as a task for the future.
Additionally, since this error is thrown from over 100 places in the
codebase, introduce a dedicated function to throw it, reducing code
duplication.
Extracted from a slightly larger patch by Vignesh C. Reviewed by
Bharath Rupireddy, Alvaro Herrera, Dilip Kumar, Hou Zhijie, Peter
Smith, Daniel Gustafsson, Julien Rouhaud and me.
Discussion: https://postgr.es/m/CALDaNm33FFSS5tVyvmkoK2cCMuDVxcui=gFrjti9ROfynqSAGA@mail.gmail.com
2021-07-15 09:49:45 +02:00
|
|
|
parse_func_options(pstate, stmt->func_options,
|
2011-02-19 06:06:18 +01:00
|
|
|
&handler_given, &fdwhandler,
|
|
|
|
&validator_given, &fdwvalidator);
|
2009-02-24 11:06:36 +01:00
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
values[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = ObjectIdGetDatum(fdwhandler);
|
|
|
|
values[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = ObjectIdGetDatum(fdwvalidator);
|
2009-02-24 11:06:36 +01:00
|
|
|
|
|
|
|
nulls[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2009-12-23 13:23:59 +01:00
|
|
|
fdwoptions = transformGenericOptions(ForeignDataWrapperRelationId,
|
|
|
|
PointerGetDatum(NULL),
|
|
|
|
stmt->options,
|
2009-02-24 11:06:36 +01:00
|
|
|
fdwvalidator);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2008-12-20 10:40:56 +01:00
|
|
|
if (PointerIsValid(DatumGetPointer(fdwoptions)))
|
2008-12-19 17:25:19 +01:00
|
|
|
values[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = fdwoptions;
|
|
|
|
else
|
|
|
|
nulls[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
|
|
|
|
|
|
|
|
tuple = heap_form_tuple(rel->rd_att, values, nulls);
|
|
|
|
|
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
|
|
|
CatalogTupleInsert(rel, tuple);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
heap_freetuple(tuple);
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* record dependencies */
|
|
|
|
myself.classId = ForeignDataWrapperRelationId;
|
|
|
|
myself.objectId = fdwId;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
if (OidIsValid(fdwhandler))
|
|
|
|
{
|
|
|
|
referenced.classId = ProcedureRelationId;
|
|
|
|
referenced.objectId = fdwhandler;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OidIsValid(fdwvalidator))
|
2009-02-24 11:06:36 +01:00
|
|
|
{
|
|
|
|
referenced.classId = ProcedureRelationId;
|
|
|
|
referenced.objectId = fdwvalidator;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
}
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
recordDependencyOnOwner(ForeignDataWrapperRelationId, fdwId, ownerId);
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* dependency on extension */
|
2011-07-23 22:59:39 +02:00
|
|
|
recordDependencyOnCurrentExtension(&myself, false);
|
2011-02-08 22:08:41 +01:00
|
|
|
|
2010-11-25 17:48:49 +01:00
|
|
|
/* Post creation hook for new foreign data wrapper */
|
2013-03-07 02:52:06 +01:00
|
|
|
InvokeObjectPostCreateHook(ForeignDataWrapperRelationId, fdwId, 0);
|
2010-11-25 17:48:49 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-12-29 13:55:37 +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 myself;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Alter foreign-data wrapper
|
|
|
|
*/
|
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
|
Improve reporting of "conflicting or redundant options" errors.
When reporting "conflicting or redundant options" errors, try to
ensure that errposition() is used, to help the user identify the
offending option.
Formerly, errposition() was invoked in less than 60% of cases. This
patch raises that to over 90%, but there remain a few places where the
ParseState is not readily available. Using errdetail() might improve
the error in such cases, but that is left as a task for the future.
Additionally, since this error is thrown from over 100 places in the
codebase, introduce a dedicated function to throw it, reducing code
duplication.
Extracted from a slightly larger patch by Vignesh C. Reviewed by
Bharath Rupireddy, Alvaro Herrera, Dilip Kumar, Hou Zhijie, Peter
Smith, Daniel Gustafsson, Julien Rouhaud and me.
Discussion: https://postgr.es/m/CALDaNm33FFSS5tVyvmkoK2cCMuDVxcui=gFrjti9ROfynqSAGA@mail.gmail.com
2021-07-15 09:49:45 +02:00
|
|
|
AlterForeignDataWrapper(ParseState *pstate, AlterFdwStmt *stmt)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
|
|
|
Relation rel;
|
|
|
|
HeapTuple tp;
|
2011-02-19 06:06:18 +01:00
|
|
|
Form_pg_foreign_data_wrapper fdwForm;
|
2008-12-19 17:25:19 +01:00
|
|
|
Datum repl_val[Natts_pg_foreign_data_wrapper];
|
|
|
|
bool repl_null[Natts_pg_foreign_data_wrapper];
|
|
|
|
bool repl_repl[Natts_pg_foreign_data_wrapper];
|
|
|
|
Oid fdwId;
|
|
|
|
bool isnull;
|
|
|
|
Datum datum;
|
2011-02-19 06:06:18 +01:00
|
|
|
bool handler_given;
|
|
|
|
bool validator_given;
|
|
|
|
Oid fdwhandler;
|
2009-02-24 11:06:36 +01:00
|
|
|
Oid fdwvalidator;
|
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 myself;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignDataWrapperRelationId, RowExclusiveLock);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
2021-09-08 17:02:18 +02:00
|
|
|
/* Must be superuser */
|
2008-12-19 17:25:19 +01:00
|
|
|
if (!superuser())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("permission denied to alter foreign-data wrapper \"%s\"",
|
|
|
|
stmt->fdwname),
|
|
|
|
errhint("Must be superuser to alter a foreign-data wrapper.")));
|
|
|
|
|
2010-02-14 19:42:19 +01:00
|
|
|
tp = SearchSysCacheCopy1(FOREIGNDATAWRAPPERNAME,
|
|
|
|
CStringGetDatum(stmt->fdwname));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tp))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("foreign-data wrapper \"%s\" does not exist", stmt->fdwname)));
|
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp);
|
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
|
|
|
fdwId = fdwForm->oid;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
memset(repl_val, 0, sizeof(repl_val));
|
|
|
|
memset(repl_null, false, sizeof(repl_null));
|
|
|
|
memset(repl_repl, false, sizeof(repl_repl));
|
|
|
|
|
Improve reporting of "conflicting or redundant options" errors.
When reporting "conflicting or redundant options" errors, try to
ensure that errposition() is used, to help the user identify the
offending option.
Formerly, errposition() was invoked in less than 60% of cases. This
patch raises that to over 90%, but there remain a few places where the
ParseState is not readily available. Using errdetail() might improve
the error in such cases, but that is left as a task for the future.
Additionally, since this error is thrown from over 100 places in the
codebase, introduce a dedicated function to throw it, reducing code
duplication.
Extracted from a slightly larger patch by Vignesh C. Reviewed by
Bharath Rupireddy, Alvaro Herrera, Dilip Kumar, Hou Zhijie, Peter
Smith, Daniel Gustafsson, Julien Rouhaud and me.
Discussion: https://postgr.es/m/CALDaNm33FFSS5tVyvmkoK2cCMuDVxcui=gFrjti9ROfynqSAGA@mail.gmail.com
2021-07-15 09:49:45 +02:00
|
|
|
parse_func_options(pstate, stmt->func_options,
|
2011-02-19 06:06:18 +01:00
|
|
|
&handler_given, &fdwhandler,
|
|
|
|
&validator_given, &fdwvalidator);
|
|
|
|
|
|
|
|
if (handler_given)
|
|
|
|
{
|
|
|
|
repl_val[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = ObjectIdGetDatum(fdwhandler);
|
|
|
|
repl_repl[Anum_pg_foreign_data_wrapper_fdwhandler - 1] = true;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* It could be that the behavior of accessing foreign table changes
|
|
|
|
* with the new handler. Warn about this.
|
|
|
|
*/
|
|
|
|
ereport(WARNING,
|
|
|
|
(errmsg("changing the foreign-data wrapper handler can change behavior of existing foreign tables")));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (validator_given)
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
2009-02-24 11:06:36 +01:00
|
|
|
repl_val[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = ObjectIdGetDatum(fdwvalidator);
|
|
|
|
repl_repl[Anum_pg_foreign_data_wrapper_fdwvalidator - 1] = true;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/*
|
2013-10-28 15:28:35 +01:00
|
|
|
* It could be that existing options for the FDW or dependent SERVER,
|
|
|
|
* USER MAPPING or FOREIGN TABLE objects are no longer valid according
|
|
|
|
* to the new validator. Warn about this.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
2011-02-19 06:06:18 +01:00
|
|
|
if (OidIsValid(fdwvalidator))
|
2009-02-24 11:06:36 +01:00
|
|
|
ereport(WARNING,
|
2011-02-19 06:06:18 +01:00
|
|
|
(errmsg("changing the foreign-data wrapper validator can cause "
|
|
|
|
"the options for dependent objects to become invalid")));
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
2009-02-24 11:06:36 +01:00
|
|
|
* Validator is not changed, but we need it for validating options.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
2011-02-19 06:06:18 +01:00
|
|
|
fdwvalidator = fdwForm->fdwvalidator;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-02-19 06:06:18 +01:00
|
|
|
* If options specified, validate and update.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
|
|
|
if (stmt->options)
|
|
|
|
{
|
|
|
|
/* Extract the current options */
|
|
|
|
datum = SysCacheGetAttr(FOREIGNDATAWRAPPEROID,
|
|
|
|
tp,
|
|
|
|
Anum_pg_foreign_data_wrapper_fdwoptions,
|
|
|
|
&isnull);
|
2008-12-20 16:51:28 +01:00
|
|
|
if (isnull)
|
|
|
|
datum = PointerGetDatum(NULL);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* Transform the options */
|
2009-12-23 13:23:59 +01:00
|
|
|
datum = transformGenericOptions(ForeignDataWrapperRelationId,
|
|
|
|
datum,
|
|
|
|
stmt->options,
|
|
|
|
fdwvalidator);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2008-12-20 10:40:56 +01:00
|
|
|
if (PointerIsValid(DatumGetPointer(datum)))
|
2008-12-20 16:51:28 +01:00
|
|
|
repl_val[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = datum;
|
2008-12-19 17:25:19 +01:00
|
|
|
else
|
|
|
|
repl_null[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
|
|
|
|
|
|
|
|
repl_repl[Anum_pg_foreign_data_wrapper_fdwoptions - 1] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Everything looks good - update the tuple */
|
|
|
|
tp = heap_modify_tuple(tp, RelationGetDescr(rel),
|
|
|
|
repl_val, repl_null, repl_repl);
|
|
|
|
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &tp->t_self, tp);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
heap_freetuple(tp);
|
2011-02-19 06:06:18 +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
|
|
|
ObjectAddressSet(myself, ForeignDataWrapperRelationId, fdwId);
|
|
|
|
|
2011-02-19 06:06:18 +01:00
|
|
|
/* Update function dependencies if we changed them */
|
|
|
|
if (handler_given || validator_given)
|
|
|
|
{
|
|
|
|
ObjectAddress referenced;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Flush all existing dependency records of this FDW on functions; we
|
|
|
|
* assume there can be none other than the ones we are fixing.
|
|
|
|
*/
|
|
|
|
deleteDependencyRecordsForClass(ForeignDataWrapperRelationId,
|
|
|
|
fdwId,
|
|
|
|
ProcedureRelationId,
|
|
|
|
DEPENDENCY_NORMAL);
|
|
|
|
|
|
|
|
/* And build new ones. */
|
|
|
|
|
|
|
|
if (OidIsValid(fdwhandler))
|
|
|
|
{
|
|
|
|
referenced.classId = ProcedureRelationId;
|
|
|
|
referenced.objectId = fdwhandler;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OidIsValid(fdwvalidator))
|
|
|
|
{
|
|
|
|
referenced.classId = ProcedureRelationId;
|
|
|
|
referenced.objectId = fdwvalidator;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-18 03:55:14 +01:00
|
|
|
InvokeObjectPostAlterHook(ForeignDataWrapperRelationId, fdwId, 0);
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-12-29 13:55:37 +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 myself;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a foreign server
|
|
|
|
*/
|
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
|
2008-12-19 17:25:19 +01:00
|
|
|
CreateForeignServer(CreateForeignServerStmt *stmt)
|
|
|
|
{
|
|
|
|
Relation rel;
|
2008-12-20 10:40:56 +01:00
|
|
|
Datum srvoptions;
|
2008-12-19 17:25:19 +01:00
|
|
|
Datum values[Natts_pg_foreign_server];
|
|
|
|
bool nulls[Natts_pg_foreign_server];
|
|
|
|
HeapTuple tuple;
|
|
|
|
Oid srvId;
|
|
|
|
Oid ownerId;
|
|
|
|
AclResult aclresult;
|
|
|
|
ObjectAddress myself;
|
|
|
|
ObjectAddress referenced;
|
|
|
|
ForeignDataWrapper *fdw;
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignServerRelationId, RowExclusiveLock);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
/* For now the owner cannot be specified on create. Use effective user ID. */
|
|
|
|
ownerId = GetUserId();
|
|
|
|
|
|
|
|
/*
|
2022-08-08 17:12:31 +02:00
|
|
|
* Check that there is no other foreign server by this name. If there is
|
|
|
|
* one, do nothing if IF NOT EXISTS was specified.
|
2008-12-19 17:25:19 +01:00
|
|
|
*/
|
2022-08-08 17:12:31 +02:00
|
|
|
srvId = get_foreign_server_oid(stmt->servername, true);
|
|
|
|
if (OidIsValid(srvId))
|
2017-03-20 21:40:45 +01:00
|
|
|
{
|
|
|
|
if (stmt->if_not_exists)
|
|
|
|
{
|
2022-08-08 17:12:31 +02:00
|
|
|
/*
|
|
|
|
* If we are in an extension script, insist that the pre-existing
|
|
|
|
* object be a member of the extension, to avoid security risks.
|
|
|
|
*/
|
|
|
|
ObjectAddressSet(myself, ForeignServerRelationId, srvId);
|
|
|
|
checkMembershipInCurrentExtension(&myself);
|
|
|
|
|
|
|
|
/* OK to skip */
|
2017-03-20 21:40:45 +01:00
|
|
|
ereport(NOTICE,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("server \"%s\" already exists, skipping",
|
|
|
|
stmt->servername)));
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2017-03-20 21:40:45 +01:00
|
|
|
return InvalidObjectAddress;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("server \"%s\" already exists",
|
|
|
|
stmt->servername)));
|
|
|
|
}
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that the FDW exists and that we have USAGE on it. Also get the
|
|
|
|
* actual FDW for option validation etc.
|
|
|
|
*/
|
|
|
|
fdw = GetForeignDataWrapperByName(stmt->fdwname, false);
|
|
|
|
|
2022-11-13 08:11:17 +01:00
|
|
|
aclresult = object_aclcheck(ForeignDataWrapperRelationId, fdw->fdwid, ownerId, ACL_USAGE);
|
2008-12-19 17:25:19 +01:00
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_FDW, fdw->fdwname);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Insert tuple into pg_foreign_server.
|
|
|
|
*/
|
2008-12-20 16:51:28 +01:00
|
|
|
memset(values, 0, sizeof(values));
|
|
|
|
memset(nulls, false, sizeof(nulls));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
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
|
|
|
srvId = GetNewOidWithIndex(rel, ForeignServerOidIndexId,
|
|
|
|
Anum_pg_foreign_server_oid);
|
|
|
|
values[Anum_pg_foreign_server_oid - 1] = ObjectIdGetDatum(srvId);
|
2008-12-19 17:25:19 +01:00
|
|
|
values[Anum_pg_foreign_server_srvname - 1] =
|
|
|
|
DirectFunctionCall1(namein, CStringGetDatum(stmt->servername));
|
|
|
|
values[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(ownerId);
|
|
|
|
values[Anum_pg_foreign_server_srvfdw - 1] = ObjectIdGetDatum(fdw->fdwid);
|
|
|
|
|
|
|
|
/* Add server type if supplied */
|
|
|
|
if (stmt->servertype)
|
|
|
|
values[Anum_pg_foreign_server_srvtype - 1] =
|
|
|
|
CStringGetTextDatum(stmt->servertype);
|
|
|
|
else
|
|
|
|
nulls[Anum_pg_foreign_server_srvtype - 1] = true;
|
|
|
|
|
|
|
|
/* Add server version if supplied */
|
|
|
|
if (stmt->version)
|
|
|
|
values[Anum_pg_foreign_server_srvversion - 1] =
|
|
|
|
CStringGetTextDatum(stmt->version);
|
|
|
|
else
|
|
|
|
nulls[Anum_pg_foreign_server_srvversion - 1] = true;
|
|
|
|
|
|
|
|
/* Start with a blank acl */
|
|
|
|
nulls[Anum_pg_foreign_server_srvacl - 1] = true;
|
|
|
|
|
|
|
|
/* Add server options */
|
2009-12-23 13:23:59 +01:00
|
|
|
srvoptions = transformGenericOptions(ForeignServerRelationId,
|
|
|
|
PointerGetDatum(NULL),
|
|
|
|
stmt->options,
|
2009-02-24 11:06:36 +01:00
|
|
|
fdw->fdwvalidator);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2008-12-20 10:40:56 +01:00
|
|
|
if (PointerIsValid(DatumGetPointer(srvoptions)))
|
2008-12-19 17:25:19 +01:00
|
|
|
values[Anum_pg_foreign_server_srvoptions - 1] = srvoptions;
|
|
|
|
else
|
|
|
|
nulls[Anum_pg_foreign_server_srvoptions - 1] = true;
|
|
|
|
|
|
|
|
tuple = heap_form_tuple(rel->rd_att, values, nulls);
|
|
|
|
|
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
|
|
|
CatalogTupleInsert(rel, tuple);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
heap_freetuple(tuple);
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* record dependencies */
|
2008-12-19 17:25:19 +01:00
|
|
|
myself.classId = ForeignServerRelationId;
|
|
|
|
myself.objectId = srvId;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
|
|
|
referenced.classId = ForeignDataWrapperRelationId;
|
|
|
|
referenced.objectId = fdw->fdwid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
|
|
|
|
recordDependencyOnOwner(ForeignServerRelationId, srvId, ownerId);
|
|
|
|
|
2011-02-08 22:08:41 +01:00
|
|
|
/* dependency on extension */
|
2011-07-23 22:59:39 +02:00
|
|
|
recordDependencyOnCurrentExtension(&myself, false);
|
2011-02-08 22:08:41 +01:00
|
|
|
|
2010-11-25 17:48:49 +01:00
|
|
|
/* Post creation hook for new foreign server */
|
2013-03-07 02:52:06 +01:00
|
|
|
InvokeObjectPostCreateHook(ForeignServerRelationId, srvId, 0);
|
2010-11-25 17:48:49 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-12-29 13:55:37 +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 myself;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Alter foreign server
|
|
|
|
*/
|
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
|
2008-12-19 17:25:19 +01:00
|
|
|
AlterForeignServer(AlterForeignServerStmt *stmt)
|
|
|
|
{
|
|
|
|
Relation rel;
|
|
|
|
HeapTuple tp;
|
|
|
|
Datum repl_val[Natts_pg_foreign_server];
|
|
|
|
bool repl_null[Natts_pg_foreign_server];
|
|
|
|
bool repl_repl[Natts_pg_foreign_server];
|
|
|
|
Oid srvId;
|
|
|
|
Form_pg_foreign_server srvForm;
|
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;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(ForeignServerRelationId, RowExclusiveLock);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
2010-02-14 19:42:19 +01:00
|
|
|
tp = SearchSysCacheCopy1(FOREIGNSERVERNAME,
|
|
|
|
CStringGetDatum(stmt->servername));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tp))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("server \"%s\" does not exist", stmt->servername)));
|
|
|
|
|
|
|
|
srvForm = (Form_pg_foreign_server) GETSTRUCT(tp);
|
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
|
|
|
srvId = srvForm->oid;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Only owner or a superuser can ALTER a SERVER.
|
|
|
|
*/
|
2022-11-13 08:11:17 +01:00
|
|
|
if (!object_ownercheck(ForeignServerRelationId, srvId, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FOREIGN_SERVER,
|
2008-12-19 17:25:19 +01:00
|
|
|
stmt->servername);
|
|
|
|
|
|
|
|
memset(repl_val, 0, sizeof(repl_val));
|
|
|
|
memset(repl_null, false, sizeof(repl_null));
|
|
|
|
memset(repl_repl, false, sizeof(repl_repl));
|
|
|
|
|
|
|
|
if (stmt->has_version)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Change the server VERSION string.
|
|
|
|
*/
|
|
|
|
if (stmt->version)
|
|
|
|
repl_val[Anum_pg_foreign_server_srvversion - 1] =
|
|
|
|
CStringGetTextDatum(stmt->version);
|
|
|
|
else
|
|
|
|
repl_null[Anum_pg_foreign_server_srvversion - 1] = true;
|
|
|
|
|
|
|
|
repl_repl[Anum_pg_foreign_server_srvversion - 1] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stmt->options)
|
|
|
|
{
|
|
|
|
ForeignDataWrapper *fdw = GetForeignDataWrapper(srvForm->srvfdw);
|
|
|
|
Datum datum;
|
|
|
|
bool isnull;
|
|
|
|
|
|
|
|
/* Extract the current srvoptions */
|
|
|
|
datum = SysCacheGetAttr(FOREIGNSERVEROID,
|
|
|
|
tp,
|
|
|
|
Anum_pg_foreign_server_srvoptions,
|
|
|
|
&isnull);
|
2008-12-20 16:51:28 +01:00
|
|
|
if (isnull)
|
|
|
|
datum = PointerGetDatum(NULL);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* Prepare the options array */
|
2009-12-23 13:23:59 +01:00
|
|
|
datum = transformGenericOptions(ForeignServerRelationId,
|
|
|
|
datum,
|
|
|
|
stmt->options,
|
2009-04-04 23:12:31 +02:00
|
|
|
fdw->fdwvalidator);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2008-12-20 10:40:56 +01:00
|
|
|
if (PointerIsValid(DatumGetPointer(datum)))
|
2008-12-19 17:25:19 +01:00
|
|
|
repl_val[Anum_pg_foreign_server_srvoptions - 1] = datum;
|
|
|
|
else
|
|
|
|
repl_null[Anum_pg_foreign_server_srvoptions - 1] = true;
|
|
|
|
|
|
|
|
repl_repl[Anum_pg_foreign_server_srvoptions - 1] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Everything looks good - update the tuple */
|
|
|
|
tp = heap_modify_tuple(tp, RelationGetDescr(rel),
|
|
|
|
repl_val, repl_null, repl_repl);
|
|
|
|
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &tp->t_self, tp);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2013-03-18 03:55:14 +01:00
|
|
|
InvokeObjectPostAlterHook(ForeignServerRelationId, srvId, 0);
|
|
|
|
|
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
|
|
|
ObjectAddressSet(address, ForeignServerRelationId, srvId);
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
heap_freetuple(tp);
|
2011-02-19 06:06:18 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-12-29 13:55:37 +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;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-20 10:10:20 +01:00
|
|
|
/*
|
|
|
|
* Common routine to check permission for user-mapping-related DDL
|
|
|
|
* commands. We allow server owners to operate on any mapping, and
|
|
|
|
* users to operate on their own mapping.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
user_mapping_ddl_aclcheck(Oid umuserid, Oid serverid, const char *servername)
|
|
|
|
{
|
|
|
|
Oid curuserid = GetUserId();
|
|
|
|
|
2022-11-13 08:11:17 +01:00
|
|
|
if (!object_ownercheck(ForeignServerRelationId, serverid, curuserid))
|
2009-01-20 10:10:20 +01:00
|
|
|
{
|
|
|
|
if (umuserid == curuserid)
|
|
|
|
{
|
|
|
|
AclResult aclresult;
|
|
|
|
|
2022-11-13 08:11:17 +01:00
|
|
|
aclresult = object_aclcheck(ForeignServerRelationId, serverid, curuserid, ACL_USAGE);
|
2009-01-20 10:10:20 +01:00
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, servername);
|
2009-01-20 10:10:20 +01:00
|
|
|
}
|
|
|
|
else
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FOREIGN_SERVER,
|
2009-01-20 10:10:20 +01:00
|
|
|
servername);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
/*
|
|
|
|
* Create user mapping
|
|
|
|
*/
|
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
|
2008-12-19 17:25:19 +01:00
|
|
|
CreateUserMapping(CreateUserMappingStmt *stmt)
|
|
|
|
{
|
|
|
|
Relation rel;
|
2008-12-20 10:40:56 +01:00
|
|
|
Datum useoptions;
|
2008-12-19 17:25:19 +01:00
|
|
|
Datum values[Natts_pg_user_mapping];
|
|
|
|
bool nulls[Natts_pg_user_mapping];
|
|
|
|
HeapTuple tuple;
|
|
|
|
Oid useId;
|
|
|
|
Oid umId;
|
|
|
|
ObjectAddress myself;
|
|
|
|
ObjectAddress referenced;
|
|
|
|
ForeignServer *srv;
|
|
|
|
ForeignDataWrapper *fdw;
|
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
|
|
|
RoleSpec *role = (RoleSpec *) stmt->user;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(UserMappingRelationId, RowExclusiveLock);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
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
|
|
|
if (role->roletype == ROLESPEC_PUBLIC)
|
|
|
|
useId = ACL_ID_PUBLIC;
|
|
|
|
else
|
|
|
|
useId = get_rolespec_oid(stmt->user, false);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2009-01-20 10:10:20 +01:00
|
|
|
/* Check that the server exists. */
|
2008-12-19 17:25:19 +01:00
|
|
|
srv = GetForeignServerByName(stmt->servername, false);
|
|
|
|
|
2009-01-20 10:10:20 +01:00
|
|
|
user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that the user mapping is unique within server.
|
|
|
|
*/
|
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
|
|
|
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid,
|
2010-02-14 19:42:19 +01:00
|
|
|
ObjectIdGetDatum(useId),
|
|
|
|
ObjectIdGetDatum(srv->serverid));
|
2017-03-20 21:40:45 +01:00
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
if (OidIsValid(umId))
|
2017-03-20 21:40:45 +01:00
|
|
|
{
|
|
|
|
if (stmt->if_not_exists)
|
|
|
|
{
|
2022-08-08 17:12:31 +02:00
|
|
|
/*
|
|
|
|
* Since user mappings aren't members of extensions (see comments
|
|
|
|
* below), no need for checkMembershipInCurrentExtension here.
|
|
|
|
*/
|
2017-03-20 21:40:45 +01:00
|
|
|
ereport(NOTICE,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
2019-05-08 19:16:54 +02:00
|
|
|
errmsg("user mapping for \"%s\" already exists for server \"%s\", skipping",
|
2017-03-20 21:40:45 +01:00
|
|
|
MappingUserName(useId),
|
|
|
|
stmt->servername)));
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2017-03-20 21:40:45 +01:00
|
|
|
return InvalidObjectAddress;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ereport(ERROR,
|
2008-12-19 17:25:19 +01:00
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
2019-05-08 19:16:54 +02:00
|
|
|
errmsg("user mapping for \"%s\" already exists for server \"%s\"",
|
2008-12-19 17:25:19 +01:00
|
|
|
MappingUserName(useId),
|
|
|
|
stmt->servername)));
|
2017-03-20 21:40:45 +01:00
|
|
|
}
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
fdw = GetForeignDataWrapper(srv->fdwid);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Insert tuple into pg_user_mapping.
|
|
|
|
*/
|
2008-12-20 16:51:28 +01:00
|
|
|
memset(values, 0, sizeof(values));
|
|
|
|
memset(nulls, false, sizeof(nulls));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
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
|
|
|
umId = GetNewOidWithIndex(rel, UserMappingOidIndexId,
|
|
|
|
Anum_pg_user_mapping_oid);
|
|
|
|
values[Anum_pg_user_mapping_oid - 1] = ObjectIdGetDatum(umId);
|
2008-12-19 17:25:19 +01:00
|
|
|
values[Anum_pg_user_mapping_umuser - 1] = ObjectIdGetDatum(useId);
|
|
|
|
values[Anum_pg_user_mapping_umserver - 1] = ObjectIdGetDatum(srv->serverid);
|
|
|
|
|
|
|
|
/* Add user options */
|
2009-12-23 13:23:59 +01:00
|
|
|
useoptions = transformGenericOptions(UserMappingRelationId,
|
|
|
|
PointerGetDatum(NULL),
|
|
|
|
stmt->options,
|
2009-04-04 23:12:31 +02:00
|
|
|
fdw->fdwvalidator);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2008-12-20 10:40:56 +01:00
|
|
|
if (PointerIsValid(DatumGetPointer(useoptions)))
|
2008-12-19 17:25:19 +01:00
|
|
|
values[Anum_pg_user_mapping_umoptions - 1] = useoptions;
|
|
|
|
else
|
|
|
|
nulls[Anum_pg_user_mapping_umoptions - 1] = true;
|
|
|
|
|
|
|
|
tuple = heap_form_tuple(rel->rd_att, values, nulls);
|
|
|
|
|
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
|
|
|
CatalogTupleInsert(rel, tuple);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
heap_freetuple(tuple);
|
|
|
|
|
|
|
|
/* Add dependency on the server */
|
|
|
|
myself.classId = UserMappingRelationId;
|
|
|
|
myself.objectId = umId;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
|
|
|
referenced.classId = ForeignServerRelationId;
|
|
|
|
referenced.objectId = srv->serverid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
|
|
|
|
if (OidIsValid(useId))
|
2011-02-08 22:08:41 +01:00
|
|
|
{
|
2008-12-19 17:25:19 +01:00
|
|
|
/* Record the mapped user dependency */
|
|
|
|
recordDependencyOnOwner(UserMappingRelationId, umId, useId);
|
2011-02-08 22:08:41 +01:00
|
|
|
}
|
|
|
|
|
2018-08-07 22:32:50 +02:00
|
|
|
/*
|
|
|
|
* Perhaps someday there should be a recordDependencyOnCurrentExtension
|
|
|
|
* call here; but since roles aren't members of extensions, it seems like
|
|
|
|
* user mappings shouldn't be either. Note that the grammar and pg_dump
|
|
|
|
* would need to be extended too if we change this.
|
|
|
|
*/
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2010-11-25 17:48:49 +01:00
|
|
|
/* Post creation hook for new user mapping */
|
2013-03-07 02:52:06 +01:00
|
|
|
InvokeObjectPostCreateHook(UserMappingRelationId, umId, 0);
|
2010-11-25 17:48:49 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-12-29 13:55:37 +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 myself;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Alter user mapping
|
|
|
|
*/
|
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
|
2008-12-19 17:25:19 +01:00
|
|
|
AlterUserMapping(AlterUserMappingStmt *stmt)
|
|
|
|
{
|
|
|
|
Relation rel;
|
|
|
|
HeapTuple tp;
|
|
|
|
Datum repl_val[Natts_pg_user_mapping];
|
|
|
|
bool repl_null[Natts_pg_user_mapping];
|
|
|
|
bool repl_repl[Natts_pg_user_mapping];
|
|
|
|
Oid useId;
|
|
|
|
Oid umId;
|
|
|
|
ForeignServer *srv;
|
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;
|
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
|
|
|
RoleSpec *role = (RoleSpec *) stmt->user;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(UserMappingRelationId, RowExclusiveLock);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
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
|
|
|
if (role->roletype == ROLESPEC_PUBLIC)
|
|
|
|
useId = ACL_ID_PUBLIC;
|
|
|
|
else
|
|
|
|
useId = get_rolespec_oid(stmt->user, false);
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
srv = GetForeignServerByName(stmt->servername, false);
|
|
|
|
|
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
|
|
|
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid,
|
2010-02-14 19:42:19 +01:00
|
|
|
ObjectIdGetDatum(useId),
|
|
|
|
ObjectIdGetDatum(srv->serverid));
|
2008-12-19 17:25:19 +01:00
|
|
|
if (!OidIsValid(umId))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2019-05-08 19:16:54 +02:00
|
|
|
errmsg("user mapping for \"%s\" does not exist for server \"%s\"",
|
|
|
|
MappingUserName(useId), stmt->servername)));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2009-01-20 10:10:20 +01:00
|
|
|
user_mapping_ddl_aclcheck(useId, srv->serverid, stmt->servername);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2010-02-14 19:42:19 +01:00
|
|
|
tp = SearchSysCacheCopy1(USERMAPPINGOID, ObjectIdGetDatum(umId));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
if (!HeapTupleIsValid(tp))
|
|
|
|
elog(ERROR, "cache lookup failed for user mapping %u", umId);
|
|
|
|
|
|
|
|
memset(repl_val, 0, sizeof(repl_val));
|
|
|
|
memset(repl_null, false, sizeof(repl_null));
|
|
|
|
memset(repl_repl, false, sizeof(repl_repl));
|
|
|
|
|
|
|
|
if (stmt->options)
|
|
|
|
{
|
|
|
|
ForeignDataWrapper *fdw;
|
|
|
|
Datum datum;
|
|
|
|
bool isnull;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Process the options.
|
|
|
|
*/
|
|
|
|
|
|
|
|
fdw = GetForeignDataWrapper(srv->fdwid);
|
|
|
|
|
|
|
|
datum = SysCacheGetAttr(USERMAPPINGUSERSERVER,
|
|
|
|
tp,
|
|
|
|
Anum_pg_user_mapping_umoptions,
|
|
|
|
&isnull);
|
2008-12-20 16:51:28 +01:00
|
|
|
if (isnull)
|
|
|
|
datum = PointerGetDatum(NULL);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* Prepare the options array */
|
2009-12-23 13:23:59 +01:00
|
|
|
datum = transformGenericOptions(UserMappingRelationId,
|
|
|
|
datum,
|
|
|
|
stmt->options,
|
2009-04-04 23:12:31 +02:00
|
|
|
fdw->fdwvalidator);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2008-12-20 10:40:56 +01:00
|
|
|
if (PointerIsValid(DatumGetPointer(datum)))
|
2008-12-19 17:25:19 +01:00
|
|
|
repl_val[Anum_pg_user_mapping_umoptions - 1] = datum;
|
|
|
|
else
|
|
|
|
repl_null[Anum_pg_user_mapping_umoptions - 1] = true;
|
|
|
|
|
|
|
|
repl_repl[Anum_pg_user_mapping_umoptions - 1] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Everything looks good - update the tuple */
|
|
|
|
tp = heap_modify_tuple(tp, RelationGetDescr(rel),
|
|
|
|
repl_val, repl_null, repl_repl);
|
|
|
|
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleUpdate(rel, &tp->t_self, tp);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
2020-05-23 07:03:04 +02:00
|
|
|
InvokeObjectPostAlterHook(UserMappingRelationId,
|
|
|
|
umId, 0);
|
|
|
|
|
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
|
|
|
ObjectAddressSet(address, UserMappingRelationId, umId);
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
heap_freetuple(tp);
|
2011-02-19 06:06:18 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2012-12-29 13:55:37 +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;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Drop user mapping
|
|
|
|
*/
|
2012-12-29 13:55:37 +01:00
|
|
|
Oid
|
2008-12-19 17:25:19 +01:00
|
|
|
RemoveUserMapping(DropUserMappingStmt *stmt)
|
|
|
|
{
|
|
|
|
ObjectAddress object;
|
|
|
|
Oid useId;
|
|
|
|
Oid umId;
|
|
|
|
ForeignServer *srv;
|
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
|
|
|
RoleSpec *role = (RoleSpec *) stmt->user;
|
2008-12-19 17:25:19 +01:00
|
|
|
|
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
|
|
|
if (role->roletype == ROLESPEC_PUBLIC)
|
|
|
|
useId = ACL_ID_PUBLIC;
|
|
|
|
else
|
2008-12-19 17:25:19 +01:00
|
|
|
{
|
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
|
|
|
useId = get_rolespec_oid(stmt->user, stmt->missing_ok);
|
|
|
|
if (!OidIsValid(useId))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* IF EXISTS specified, role not found and not public. Notice this
|
|
|
|
* and leave.
|
|
|
|
*/
|
|
|
|
elog(NOTICE, "role \"%s\" does not exist, skipping",
|
|
|
|
role->rolename);
|
|
|
|
return InvalidOid;
|
|
|
|
}
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
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
|
|
|
srv = GetForeignServerByName(stmt->servername, true);
|
|
|
|
|
2008-12-19 17:25:19 +01:00
|
|
|
if (!srv)
|
|
|
|
{
|
|
|
|
if (!stmt->missing_ok)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("server \"%s\" does not exist",
|
|
|
|
stmt->servername)));
|
|
|
|
/* IF EXISTS, just note it */
|
2019-05-08 19:16:54 +02:00
|
|
|
ereport(NOTICE,
|
|
|
|
(errmsg("server \"%s\" does not exist, skipping",
|
|
|
|
stmt->servername)));
|
2012-12-29 13:55:37 +01:00
|
|
|
return InvalidOid;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
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
|
|
|
umId = GetSysCacheOid2(USERMAPPINGUSERSERVER, Anum_pg_user_mapping_oid,
|
2010-02-14 19:42:19 +01:00
|
|
|
ObjectIdGetDatum(useId),
|
|
|
|
ObjectIdGetDatum(srv->serverid));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
if (!OidIsValid(umId))
|
|
|
|
{
|
|
|
|
if (!stmt->missing_ok)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
2019-05-08 19:16:54 +02:00
|
|
|
errmsg("user mapping for \"%s\" does not exist for server \"%s\"",
|
|
|
|
MappingUserName(useId), stmt->servername)));
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/* IF EXISTS specified, just note it */
|
|
|
|
ereport(NOTICE,
|
2019-05-08 19:16:54 +02:00
|
|
|
(errmsg("user mapping for \"%s\" does not exist for server \"%s\", skipping",
|
|
|
|
MappingUserName(useId), stmt->servername)));
|
2012-12-29 13:55:37 +01:00
|
|
|
return InvalidOid;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
2009-01-20 10:10:20 +01:00
|
|
|
user_mapping_ddl_aclcheck(useId, srv->serverid, srv->servername);
|
2008-12-19 17:25:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Do the deletion
|
|
|
|
*/
|
|
|
|
object.classId = UserMappingRelationId;
|
|
|
|
object.objectId = umId;
|
|
|
|
object.objectSubId = 0;
|
|
|
|
|
2012-01-26 15:24:54 +01:00
|
|
|
performDeletion(&object, DROP_CASCADE, 0);
|
2012-12-29 13:55:37 +01:00
|
|
|
|
|
|
|
return umId;
|
2008-12-19 17:25:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-01-02 05:48:11 +01:00
|
|
|
/*
|
|
|
|
* Create a foreign table
|
|
|
|
* call after DefineRelation().
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
|
|
|
|
{
|
|
|
|
Relation ftrel;
|
|
|
|
Datum ftoptions;
|
|
|
|
Datum values[Natts_pg_foreign_table];
|
|
|
|
bool nulls[Natts_pg_foreign_table];
|
|
|
|
HeapTuple tuple;
|
|
|
|
AclResult aclresult;
|
|
|
|
ObjectAddress myself;
|
|
|
|
ObjectAddress referenced;
|
|
|
|
Oid ownerId;
|
|
|
|
ForeignDataWrapper *fdw;
|
|
|
|
ForeignServer *server;
|
|
|
|
|
|
|
|
/*
|
2011-08-14 21:40:21 +02:00
|
|
|
* Advance command counter to ensure the pg_attribute tuple is visible;
|
|
|
|
* the tuple might be updated to add constraints in previous step.
|
2011-01-02 05:48:11 +01:00
|
|
|
*/
|
|
|
|
CommandCounterIncrement();
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
ftrel = table_open(ForeignTableRelationId, RowExclusiveLock);
|
2011-08-14 21:40:21 +02:00
|
|
|
|
2011-01-02 05:48:11 +01:00
|
|
|
/*
|
|
|
|
* For now the owner cannot be specified on create. Use effective user ID.
|
|
|
|
*/
|
|
|
|
ownerId = GetUserId();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check that the foreign server exists and that we have USAGE on it. Also
|
|
|
|
* get the actual FDW for option validation etc.
|
|
|
|
*/
|
|
|
|
server = GetForeignServerByName(stmt->servername, false);
|
2022-11-13 08:11:17 +01:00
|
|
|
aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, ownerId, ACL_USAGE);
|
2011-01-02 05:48:11 +01:00
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
|
2011-01-02 05:48:11 +01:00
|
|
|
|
|
|
|
fdw = GetForeignDataWrapper(server->fdwid);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Insert tuple into pg_foreign_table.
|
|
|
|
*/
|
|
|
|
memset(values, 0, sizeof(values));
|
|
|
|
memset(nulls, false, sizeof(nulls));
|
|
|
|
|
|
|
|
values[Anum_pg_foreign_table_ftrelid - 1] = ObjectIdGetDatum(relid);
|
|
|
|
values[Anum_pg_foreign_table_ftserver - 1] = ObjectIdGetDatum(server->serverid);
|
|
|
|
/* Add table generic options */
|
|
|
|
ftoptions = transformGenericOptions(ForeignTableRelationId,
|
|
|
|
PointerGetDatum(NULL),
|
|
|
|
stmt->options,
|
|
|
|
fdw->fdwvalidator);
|
|
|
|
|
|
|
|
if (PointerIsValid(DatumGetPointer(ftoptions)))
|
|
|
|
values[Anum_pg_foreign_table_ftoptions - 1] = ftoptions;
|
|
|
|
else
|
|
|
|
nulls[Anum_pg_foreign_table_ftoptions - 1] = true;
|
|
|
|
|
|
|
|
tuple = heap_form_tuple(ftrel->rd_att, values, nulls);
|
|
|
|
|
2017-01-31 22:42:24 +01:00
|
|
|
CatalogTupleInsert(ftrel, tuple);
|
2011-01-02 05:48:11 +01:00
|
|
|
|
|
|
|
heap_freetuple(tuple);
|
|
|
|
|
|
|
|
/* Add pg_class dependency on the server */
|
|
|
|
myself.classId = RelationRelationId;
|
|
|
|
myself.objectId = relid;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
|
|
|
referenced.classId = ForeignServerRelationId;
|
|
|
|
referenced.objectId = server->serverid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(ftrel, RowExclusiveLock);
|
2011-01-02 05:48:11 +01:00
|
|
|
}
|
2014-07-10 21:01:31 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Import a foreign schema
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ImportForeignSchema(ImportForeignSchemaStmt *stmt)
|
|
|
|
{
|
|
|
|
ForeignServer *server;
|
|
|
|
ForeignDataWrapper *fdw;
|
|
|
|
FdwRoutine *fdw_routine;
|
|
|
|
AclResult aclresult;
|
|
|
|
List *cmd_list;
|
|
|
|
ListCell *lc;
|
|
|
|
|
|
|
|
/* Check that the foreign server exists and that we have USAGE on it */
|
|
|
|
server = GetForeignServerByName(stmt->server_name, false);
|
2022-11-13 08:11:17 +01:00
|
|
|
aclresult = object_aclcheck(ForeignServerRelationId, server->serverid, GetUserId(), ACL_USAGE);
|
2014-07-10 21:01:31 +02:00
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_FOREIGN_SERVER, server->servername);
|
2014-07-10 21:01:31 +02:00
|
|
|
|
|
|
|
/* Check that the schema exists and we have CREATE permissions on it */
|
|
|
|
(void) LookupCreationNamespace(stmt->local_schema);
|
|
|
|
|
|
|
|
/* Get the FDW and check it supports IMPORT */
|
|
|
|
fdw = GetForeignDataWrapper(server->fdwid);
|
|
|
|
if (!OidIsValid(fdw->fdwhandler))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
|
|
|
errmsg("foreign-data wrapper \"%s\" has no handler",
|
|
|
|
fdw->fdwname)));
|
|
|
|
fdw_routine = GetFdwRoutine(fdw->fdwhandler);
|
|
|
|
if (fdw_routine->ImportForeignSchema == NULL)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_FDW_NO_SCHEMAS),
|
|
|
|
errmsg("foreign-data wrapper \"%s\" does not support IMPORT FOREIGN SCHEMA",
|
|
|
|
fdw->fdwname)));
|
|
|
|
|
|
|
|
/* Call FDW to get a list of commands */
|
|
|
|
cmd_list = fdw_routine->ImportForeignSchema(stmt, server->serverid);
|
|
|
|
|
|
|
|
/* Parse and execute each command */
|
|
|
|
foreach(lc, cmd_list)
|
|
|
|
{
|
|
|
|
char *cmd = (char *) lfirst(lc);
|
|
|
|
import_error_callback_arg callback_arg;
|
|
|
|
ErrorContextCallback sqlerrcontext;
|
|
|
|
List *raw_parsetree_list;
|
|
|
|
ListCell *lc2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup error traceback support for ereport(). This is so that any
|
|
|
|
* error in the generated SQL will be displayed nicely.
|
|
|
|
*/
|
|
|
|
callback_arg.tablename = NULL; /* not known yet */
|
|
|
|
callback_arg.cmd = cmd;
|
|
|
|
sqlerrcontext.callback = import_error_callback;
|
|
|
|
sqlerrcontext.arg = (void *) &callback_arg;
|
|
|
|
sqlerrcontext.previous = error_context_stack;
|
|
|
|
error_context_stack = &sqlerrcontext;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse the SQL string into a list of raw parse trees.
|
|
|
|
*/
|
|
|
|
raw_parsetree_list = pg_parse_query(cmd);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Process each parse tree (we allow the FDW to put more than one
|
|
|
|
* command per string, though this isn't really advised).
|
|
|
|
*/
|
|
|
|
foreach(lc2, raw_parsetree_list)
|
|
|
|
{
|
Improve castNode notation by introducing list-extraction-specific variants.
This extends the castNode() notation introduced by commit 5bcab1114 to
provide, in one step, extraction of a list cell's pointer and coercion to
a concrete node type. For example, "lfirst_node(Foo, lc)" is the same
as "castNode(Foo, lfirst(lc))". Almost half of the uses of castNode
that have appeared so far include a list extraction call, so this is
pretty widely useful, and it saves a few more keystrokes compared to the
old way.
As with the previous patch, back-patch the addition of these macros to
pg_list.h, so that the notation will be available when back-patching.
Patch by me, after an idea of Andrew Gierth's.
Discussion: https://postgr.es/m/14197.1491841216@sss.pgh.pa.us
2017-04-10 19:51:29 +02:00
|
|
|
RawStmt *rs = lfirst_node(RawStmt, lc2);
|
Change representation of statement lists, and add statement location info.
This patch makes several changes that improve the consistency of
representation of lists of statements. It's always been the case
that the output of parse analysis is a list of Query nodes, whatever
the types of the individual statements in the list. This patch brings
similar consistency to the outputs of raw parsing and planning steps:
* The output of raw parsing is now always a list of RawStmt nodes;
the statement-type-dependent nodes are one level down from that.
* The output of pg_plan_queries() is now always a list of PlannedStmt
nodes, even for utility statements. In the case of a utility statement,
"planning" just consists of wrapping a CMD_UTILITY PlannedStmt around
the utility node. This list representation is now used in Portal and
CachedPlan plan lists, replacing the former convention of intermixing
PlannedStmts with bare utility-statement nodes.
Now, every list of statements has a consistent head-node type depending
on how far along it is in processing. This allows changing many places
that formerly used generic "Node *" pointers to use a more specific
pointer type, thus reducing the number of IsA() tests and casts needed,
as well as improving code clarity.
Also, the post-parse-analysis representation of DECLARE CURSOR is changed
so that it looks more like EXPLAIN, PREPARE, etc. That is, the contained
SELECT remains a child of the DeclareCursorStmt rather than getting flipped
around to be the other way. It's now true for both Query and PlannedStmt
that utilityStmt is non-null if and only if commandType is CMD_UTILITY.
That allows simplifying a lot of places that were testing both fields.
(I think some of those were just defensive programming, but in many places,
it was actually necessary to avoid confusing DECLARE CURSOR with SELECT.)
Because PlannedStmt carries a canSetTag field, we're also able to get rid
of some ad-hoc rules about how to reconstruct canSetTag for a bare utility
statement; specifically, the assumption that a utility is canSetTag if and
only if it's the only one in its list. While I see no near-term need for
relaxing that restriction, it's nice to get rid of the ad-hocery.
The API of ProcessUtility() is changed so that what it's passed is the
wrapper PlannedStmt not just the bare utility statement. This will affect
all users of ProcessUtility_hook, but the changes are pretty trivial; see
the affected contrib modules for examples of the minimum change needed.
(Most compilers should give pointer-type-mismatch warnings for uncorrected
code.)
There's also a change in the API of ExplainOneQuery_hook, to pass through
cursorOptions instead of expecting hook functions to know what to pick.
This is needed because of the DECLARE CURSOR changes, but really should
have been done in 9.6; it's unlikely that any extant hook functions
know about using CURSOR_OPT_PARALLEL_OK.
Finally, teach gram.y to save statement boundary locations in RawStmt
nodes, and pass those through to Query and PlannedStmt nodes. This allows
more intelligent handling of cases where a source query string contains
multiple statements. This patch doesn't actually do anything with the
information, but a follow-on patch will. (Passing this information through
cleanly is the true motivation for these changes; while I think this is all
good cleanup, it's unlikely we'd have bothered without this end goal.)
catversion bump because addition of location fields to struct Query
affects stored rules.
This patch is by me, but it owes a good deal to Fabien Coelho who did
a lot of preliminary work on the problem, and also reviewed the patch.
Discussion: https://postgr.es/m/alpine.DEB.2.20.1612200926310.29821@lancre
2017-01-14 22:02:35 +01:00
|
|
|
CreateForeignTableStmt *cstmt = (CreateForeignTableStmt *) rs->stmt;
|
|
|
|
PlannedStmt *pstmt;
|
2014-07-10 21:01:31 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Because we only allow CreateForeignTableStmt, we can skip parse
|
|
|
|
* analysis, rewrite, and planning steps here.
|
|
|
|
*/
|
|
|
|
if (!IsA(cstmt, CreateForeignTableStmt))
|
|
|
|
elog(ERROR,
|
|
|
|
"foreign-data wrapper \"%s\" returned incorrect statement type %d",
|
|
|
|
fdw->fdwname, (int) nodeTag(cstmt));
|
|
|
|
|
|
|
|
/* Ignore commands for tables excluded by filter options */
|
|
|
|
if (!IsImportableForeignTable(cstmt->base.relation->relname, stmt))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* Enable reporting of current table's name on error */
|
|
|
|
callback_arg.tablename = cstmt->base.relation->relname;
|
|
|
|
|
|
|
|
/* Ensure creation schema is the one given in IMPORT statement */
|
|
|
|
cstmt->base.relation->schemaname = pstrdup(stmt->local_schema);
|
|
|
|
|
Change representation of statement lists, and add statement location info.
This patch makes several changes that improve the consistency of
representation of lists of statements. It's always been the case
that the output of parse analysis is a list of Query nodes, whatever
the types of the individual statements in the list. This patch brings
similar consistency to the outputs of raw parsing and planning steps:
* The output of raw parsing is now always a list of RawStmt nodes;
the statement-type-dependent nodes are one level down from that.
* The output of pg_plan_queries() is now always a list of PlannedStmt
nodes, even for utility statements. In the case of a utility statement,
"planning" just consists of wrapping a CMD_UTILITY PlannedStmt around
the utility node. This list representation is now used in Portal and
CachedPlan plan lists, replacing the former convention of intermixing
PlannedStmts with bare utility-statement nodes.
Now, every list of statements has a consistent head-node type depending
on how far along it is in processing. This allows changing many places
that formerly used generic "Node *" pointers to use a more specific
pointer type, thus reducing the number of IsA() tests and casts needed,
as well as improving code clarity.
Also, the post-parse-analysis representation of DECLARE CURSOR is changed
so that it looks more like EXPLAIN, PREPARE, etc. That is, the contained
SELECT remains a child of the DeclareCursorStmt rather than getting flipped
around to be the other way. It's now true for both Query and PlannedStmt
that utilityStmt is non-null if and only if commandType is CMD_UTILITY.
That allows simplifying a lot of places that were testing both fields.
(I think some of those were just defensive programming, but in many places,
it was actually necessary to avoid confusing DECLARE CURSOR with SELECT.)
Because PlannedStmt carries a canSetTag field, we're also able to get rid
of some ad-hoc rules about how to reconstruct canSetTag for a bare utility
statement; specifically, the assumption that a utility is canSetTag if and
only if it's the only one in its list. While I see no near-term need for
relaxing that restriction, it's nice to get rid of the ad-hocery.
The API of ProcessUtility() is changed so that what it's passed is the
wrapper PlannedStmt not just the bare utility statement. This will affect
all users of ProcessUtility_hook, but the changes are pretty trivial; see
the affected contrib modules for examples of the minimum change needed.
(Most compilers should give pointer-type-mismatch warnings for uncorrected
code.)
There's also a change in the API of ExplainOneQuery_hook, to pass through
cursorOptions instead of expecting hook functions to know what to pick.
This is needed because of the DECLARE CURSOR changes, but really should
have been done in 9.6; it's unlikely that any extant hook functions
know about using CURSOR_OPT_PARALLEL_OK.
Finally, teach gram.y to save statement boundary locations in RawStmt
nodes, and pass those through to Query and PlannedStmt nodes. This allows
more intelligent handling of cases where a source query string contains
multiple statements. This patch doesn't actually do anything with the
information, but a follow-on patch will. (Passing this information through
cleanly is the true motivation for these changes; while I think this is all
good cleanup, it's unlikely we'd have bothered without this end goal.)
catversion bump because addition of location fields to struct Query
affects stored rules.
This patch is by me, but it owes a good deal to Fabien Coelho who did
a lot of preliminary work on the problem, and also reviewed the patch.
Discussion: https://postgr.es/m/alpine.DEB.2.20.1612200926310.29821@lancre
2017-01-14 22:02:35 +01:00
|
|
|
/* No planning needed, just make a wrapper PlannedStmt */
|
|
|
|
pstmt = makeNode(PlannedStmt);
|
|
|
|
pstmt->commandType = CMD_UTILITY;
|
|
|
|
pstmt->canSetTag = false;
|
|
|
|
pstmt->utilityStmt = (Node *) cstmt;
|
|
|
|
pstmt->stmt_location = rs->stmt_location;
|
|
|
|
pstmt->stmt_len = rs->stmt_len;
|
|
|
|
|
2014-07-10 21:01:31 +02:00
|
|
|
/* Execute statement */
|
Centralize the logic for protective copying of utility statements.
In the "simple Query" code path, it's fine for parse analysis or
execution of a utility statement to scribble on the statement's node
tree, since that'll just be thrown away afterwards. However it's
not fine if the node tree is in the plan cache, as then it'd be
corrupted for subsequent executions. Up to now we've dealt with
that by having individual utility-statement functions apply
copyObject() if they were going to modify the tree. But that's
prone to errors of omission. Bug #17053 from Charles Samborski
shows that CREATE/ALTER DOMAIN didn't get this memo, and can
crash if executed repeatedly from plan cache.
In the back branches, we'll just apply a narrow band-aid for that,
but in HEAD it seems prudent to have a more principled fix that
will close off the possibility of other similar bugs in future.
Hence, let's hoist the responsibility for doing copyObject up into
ProcessUtility from its children, thus ensuring that it happens for
all utility statement types.
Also, modify ProcessUtility's API so that its callers can tell it
whether a copy step is necessary. It turns out that in all cases,
the immediate caller knows whether the node tree is transient, so
this doesn't involve a huge amount of code thrashing. In this way,
while we lose a little bit in the execute-from-cache code path due
to sometimes copying node trees that wouldn't be mutated anyway,
we gain something in the simple-Query code path by not copying
throwaway node trees. Statements that are complex enough to be
expensive to copy are almost certainly ones that would have to be
copied anyway, so the loss in the cache code path shouldn't be much.
(Note that this whole problem applies only to utility statements.
Optimizable statements don't have the issue because we long ago made
the executor treat Plan trees as read-only. Perhaps someday we will
make utility statement execution act likewise, but I'm not holding
my breath.)
Discussion: https://postgr.es/m/931771.1623893989@sss.pgh.pa.us
Discussion: https://postgr.es/m/17053-3ca3f501bbc212b4@postgresql.org
2021-06-18 17:22:58 +02:00
|
|
|
ProcessUtility(pstmt, cmd, false,
|
2017-04-01 06:17:18 +02:00
|
|
|
PROCESS_UTILITY_SUBCOMMAND, NULL, NULL,
|
2014-07-10 21:01:31 +02:00
|
|
|
None_Receiver, NULL);
|
|
|
|
|
|
|
|
/* Be sure to advance the command counter between subcommands */
|
|
|
|
CommandCounterIncrement();
|
|
|
|
|
|
|
|
callback_arg.tablename = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
error_context_stack = sqlerrcontext.previous;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* error context callback to let us supply the failing SQL statement's text
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
import_error_callback(void *arg)
|
|
|
|
{
|
|
|
|
import_error_callback_arg *callback_arg = (import_error_callback_arg *) arg;
|
|
|
|
int syntaxerrposition;
|
|
|
|
|
|
|
|
/* If it's a syntax error, convert to internal syntax error report */
|
|
|
|
syntaxerrposition = geterrposition();
|
|
|
|
if (syntaxerrposition > 0)
|
|
|
|
{
|
|
|
|
errposition(0);
|
|
|
|
internalerrposition(syntaxerrposition);
|
|
|
|
internalerrquery(callback_arg->cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (callback_arg->tablename)
|
|
|
|
errcontext("importing foreign table \"%s\"",
|
|
|
|
callback_arg->tablename);
|
|
|
|
}
|