2002-07-30 00:14:11 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* opclasscmds.c
|
|
|
|
*
|
2006-12-23 01:43:13 +01:00
|
|
|
* Routines for opclass (and opfamily) manipulation commands
|
2002-07-30 00:14:11 +02:00
|
|
|
*
|
2022-01-08 01:04:57 +01:00
|
|
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
|
2002-07-30 00:14:11 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* IDENTIFICATION
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/backend/commands/opclasscmds.c
|
2002-07-30 00:14:11 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
|
2006-12-18 19:56:29 +01:00
|
|
|
#include <limits.h>
|
|
|
|
|
2019-12-27 00:09:00 +01:00
|
|
|
#include "access/genam.h"
|
2017-09-01 04:21:21 +02:00
|
|
|
#include "access/hash.h"
|
2012-08-30 22:15:44 +02:00
|
|
|
#include "access/htup_details.h"
|
2019-11-12 04:00:16 +01:00
|
|
|
#include "access/nbtree.h"
|
2008-05-12 02:00:54 +02:00
|
|
|
#include "access/sysattr.h"
|
2019-01-21 19:18:20 +01:00
|
|
|
#include "access/table.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"
|
2002-07-30 00:14:11 +02:00
|
|
|
#include "catalog/dependency.h"
|
|
|
|
#include "catalog/indexing.h"
|
2010-11-25 17:48:49 +01:00
|
|
|
#include "catalog/objectaccess.h"
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
#include "catalog/pg_am.h"
|
2002-07-30 00:14:11 +02:00
|
|
|
#include "catalog/pg_amop.h"
|
|
|
|
#include "catalog/pg_amproc.h"
|
2005-04-14 22:03:27 +02:00
|
|
|
#include "catalog/pg_namespace.h"
|
2002-07-30 00:14:11 +02:00
|
|
|
#include "catalog/pg_opclass.h"
|
2003-11-12 22:15:59 +01:00
|
|
|
#include "catalog/pg_operator.h"
|
2006-12-23 01:43:13 +01:00
|
|
|
#include "catalog/pg_opfamily.h"
|
2003-11-12 22:15:59 +01:00
|
|
|
#include "catalog/pg_proc.h"
|
2003-11-09 22:30:38 +01:00
|
|
|
#include "catalog/pg_type.h"
|
2010-11-26 23:27:23 +01:00
|
|
|
#include "commands/alter.h"
|
2002-07-30 00:14:11 +02:00
|
|
|
#include "commands/defrem.h"
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
#include "commands/event_trigger.h"
|
2002-07-30 00:14:11 +02:00
|
|
|
#include "miscadmin.h"
|
|
|
|
#include "parser/parse_func.h"
|
|
|
|
#include "parser/parse_oper.h"
|
|
|
|
#include "parser/parse_type.h"
|
|
|
|
#include "utils/builtins.h"
|
|
|
|
#include "utils/fmgroids.h"
|
|
|
|
#include "utils/lsyscache.h"
|
2008-06-19 02:46:06 +02:00
|
|
|
#include "utils/rel.h"
|
2002-07-30 00:14:11 +02:00
|
|
|
#include "utils/syscache.h"
|
|
|
|
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
static void AlterOpFamilyAdd(AlterOpFamilyStmt *stmt,
|
|
|
|
Oid amoid, Oid opfamilyoid,
|
2007-01-23 06:07:18 +01:00
|
|
|
int maxOpNumber, int maxProcNumber,
|
2022-09-20 22:09:30 +02:00
|
|
|
int optsProcNumber, List *items);
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
static void AlterOpFamilyDrop(AlterOpFamilyStmt *stmt,
|
|
|
|
Oid amoid, Oid opfamilyoid,
|
2007-01-23 06:07:18 +01:00
|
|
|
int maxOpNumber, int maxProcNumber,
|
|
|
|
List *items);
|
|
|
|
static void processTypesSpec(List *args, Oid *lefttype, Oid *righttype);
|
2006-12-23 01:43:13 +01:00
|
|
|
static void assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid);
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
static void assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid,
|
|
|
|
int opclassOptsProcNum);
|
2020-08-01 23:12:47 +02:00
|
|
|
static void addFamilyMember(List **list, OpFamilyMember *member);
|
|
|
|
static void storeOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
2007-01-23 06:07:18 +01:00
|
|
|
List *operators, bool isAdd);
|
2020-08-01 23:12:47 +02:00
|
|
|
static void storeProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
2007-01-23 06:07:18 +01:00
|
|
|
List *procedures, bool isAdd);
|
|
|
|
static void dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
|
|
|
List *operators);
|
|
|
|
static void dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
|
|
|
List *procedures);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/*
|
|
|
|
* OpFamilyCacheLookup
|
|
|
|
* Look up an existing opfamily by name.
|
|
|
|
*
|
|
|
|
* Returns a syscache tuple reference, or NULL if not found.
|
|
|
|
*/
|
|
|
|
static HeapTuple
|
2010-08-05 17:25:36 +02:00
|
|
|
OpFamilyCacheLookup(Oid amID, List *opfamilyname, bool missing_ok)
|
2006-12-23 01:43:13 +01:00
|
|
|
{
|
|
|
|
char *schemaname;
|
|
|
|
char *opfname;
|
2010-08-05 17:25:36 +02:00
|
|
|
HeapTuple htup;
|
2006-12-23 01:43:13 +01:00
|
|
|
|
|
|
|
/* deconstruct the name list */
|
|
|
|
DeconstructQualifiedName(opfamilyname, &schemaname, &opfname);
|
|
|
|
|
|
|
|
if (schemaname)
|
|
|
|
{
|
|
|
|
/* Look in specific schema only */
|
|
|
|
Oid namespaceId;
|
|
|
|
|
2014-01-23 18:40:29 +01:00
|
|
|
namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
|
|
|
|
if (!OidIsValid(namespaceId))
|
|
|
|
htup = NULL;
|
|
|
|
else
|
|
|
|
htup = SearchSysCache3(OPFAMILYAMNAMENSP,
|
|
|
|
ObjectIdGetDatum(amID),
|
|
|
|
PointerGetDatum(opfname),
|
|
|
|
ObjectIdGetDatum(namespaceId));
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Unqualified opfamily name, so search the search path */
|
|
|
|
Oid opfID = OpfamilynameGetOpfid(amID, opfname);
|
|
|
|
|
|
|
|
if (!OidIsValid(opfID))
|
2010-08-05 17:25:36 +02:00
|
|
|
htup = NULL;
|
|
|
|
else
|
|
|
|
htup = SearchSysCache1(OPFAMILYOID, ObjectIdGetDatum(opfID));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!HeapTupleIsValid(htup) && !missing_ok)
|
|
|
|
{
|
|
|
|
HeapTuple amtup;
|
|
|
|
|
|
|
|
amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
|
|
|
|
if (!HeapTupleIsValid(amtup))
|
|
|
|
elog(ERROR, "cache lookup failed for access method %u", amID);
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
|
|
|
NameListToString(opfamilyname),
|
|
|
|
NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
2010-08-05 17:25:36 +02:00
|
|
|
|
|
|
|
return htup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get_opfamily_oid
|
|
|
|
* find an opfamily OID by possibly qualified name
|
|
|
|
*
|
|
|
|
* If not found, returns InvalidOid if missing_ok, else throws error.
|
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
|
|
|
|
{
|
|
|
|
HeapTuple htup;
|
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_opfamily opfamform;
|
2010-08-05 17:25:36 +02:00
|
|
|
Oid opfID;
|
|
|
|
|
|
|
|
htup = OpFamilyCacheLookup(amID, opfamilyname, missing_ok);
|
|
|
|
if (!HeapTupleIsValid(htup))
|
|
|
|
return InvalidOid;
|
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
|
|
|
opfamform = (Form_pg_opfamily) GETSTRUCT(htup);
|
|
|
|
opfID = opfamform->oid;
|
2010-08-05 17:25:36 +02:00
|
|
|
ReleaseSysCache(htup);
|
|
|
|
|
|
|
|
return opfID;
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OpClassCacheLookup
|
|
|
|
* Look up an existing opclass by name.
|
|
|
|
*
|
|
|
|
* Returns a syscache tuple reference, or NULL if not found.
|
|
|
|
*/
|
|
|
|
static HeapTuple
|
2010-08-05 17:25:36 +02:00
|
|
|
OpClassCacheLookup(Oid amID, List *opclassname, bool missing_ok)
|
2006-12-23 01:43:13 +01:00
|
|
|
{
|
|
|
|
char *schemaname;
|
|
|
|
char *opcname;
|
2010-08-05 17:25:36 +02:00
|
|
|
HeapTuple htup;
|
2006-12-23 01:43:13 +01:00
|
|
|
|
|
|
|
/* deconstruct the name list */
|
|
|
|
DeconstructQualifiedName(opclassname, &schemaname, &opcname);
|
|
|
|
|
|
|
|
if (schemaname)
|
|
|
|
{
|
|
|
|
/* Look in specific schema only */
|
|
|
|
Oid namespaceId;
|
|
|
|
|
2014-01-23 18:40:29 +01:00
|
|
|
namespaceId = LookupExplicitNamespace(schemaname, missing_ok);
|
|
|
|
if (!OidIsValid(namespaceId))
|
|
|
|
htup = NULL;
|
|
|
|
else
|
|
|
|
htup = SearchSysCache3(CLAAMNAMENSP,
|
|
|
|
ObjectIdGetDatum(amID),
|
|
|
|
PointerGetDatum(opcname),
|
|
|
|
ObjectIdGetDatum(namespaceId));
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Unqualified opclass name, so search the search path */
|
|
|
|
Oid opcID = OpclassnameGetOpcid(amID, opcname);
|
|
|
|
|
|
|
|
if (!OidIsValid(opcID))
|
2010-08-05 17:25:36 +02:00
|
|
|
htup = NULL;
|
|
|
|
else
|
|
|
|
htup = SearchSysCache1(CLAOID, ObjectIdGetDatum(opcID));
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
2010-08-05 17:25:36 +02:00
|
|
|
|
|
|
|
if (!HeapTupleIsValid(htup) && !missing_ok)
|
|
|
|
{
|
|
|
|
HeapTuple amtup;
|
|
|
|
|
|
|
|
amtup = SearchSysCache1(AMOID, ObjectIdGetDatum(amID));
|
|
|
|
if (!HeapTupleIsValid(amtup))
|
|
|
|
elog(ERROR, "cache lookup failed for access method %u", amID);
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("operator class \"%s\" does not exist for access method \"%s\"",
|
|
|
|
NameListToString(opclassname),
|
|
|
|
NameStr(((Form_pg_am) GETSTRUCT(amtup))->amname))));
|
|
|
|
}
|
|
|
|
|
|
|
|
return htup;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get_opclass_oid
|
|
|
|
* find an opclass OID by possibly qualified name
|
|
|
|
*
|
|
|
|
* If not found, returns InvalidOid if missing_ok, else throws error.
|
|
|
|
*/
|
|
|
|
Oid
|
|
|
|
get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
|
|
|
|
{
|
|
|
|
HeapTuple htup;
|
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_opclass opcform;
|
2010-08-05 17:25:36 +02:00
|
|
|
Oid opcID;
|
|
|
|
|
|
|
|
htup = OpClassCacheLookup(amID, opclassname, missing_ok);
|
|
|
|
if (!HeapTupleIsValid(htup))
|
|
|
|
return InvalidOid;
|
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
|
|
|
opcform = (Form_pg_opclass) GETSTRUCT(htup);
|
|
|
|
opcID = opcform->oid;
|
2010-08-05 17:25:36 +02:00
|
|
|
ReleaseSysCache(htup);
|
|
|
|
|
|
|
|
return opcID;
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* CreateOpFamily
|
|
|
|
* Internal routine to make the catalog entry for a new operator family.
|
|
|
|
*
|
|
|
|
* Caller must have done permissions checks etc. already.
|
|
|
|
*/
|
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
|
|
|
static ObjectAddress
|
2022-05-20 18:52:55 +02:00
|
|
|
CreateOpFamily(CreateOpFamilyStmt *stmt, const char *opfname,
|
|
|
|
Oid namespaceoid, Oid amoid)
|
2006-12-23 01:43:13 +01:00
|
|
|
{
|
|
|
|
Oid opfamilyoid;
|
|
|
|
Relation rel;
|
|
|
|
HeapTuple tup;
|
|
|
|
Datum values[Natts_pg_opfamily];
|
2008-11-02 02:45:28 +01:00
|
|
|
bool nulls[Natts_pg_opfamily];
|
2006-12-23 01:43:13 +01:00
|
|
|
NameData opfName;
|
|
|
|
ObjectAddress myself,
|
|
|
|
referenced;
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(OperatorFamilyRelationId, RowExclusiveLock);
|
2006-12-23 01:43:13 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure there is no existing opfamily of this name (this is just to
|
|
|
|
* give a more friendly error message than "duplicate key").
|
|
|
|
*/
|
2010-02-14 19:42:19 +01:00
|
|
|
if (SearchSysCacheExists3(OPFAMILYAMNAMENSP,
|
|
|
|
ObjectIdGetDatum(amoid),
|
|
|
|
CStringGetDatum(opfname),
|
|
|
|
ObjectIdGetDatum(namespaceoid)))
|
2006-12-23 01:43:13 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("operator family \"%s\" for access method \"%s\" already exists",
|
2022-05-20 18:52:55 +02:00
|
|
|
opfname, stmt->amname)));
|
2006-12-23 01:43:13 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Okay, let's create the pg_opfamily entry.
|
|
|
|
*/
|
|
|
|
memset(values, 0, sizeof(values));
|
2008-11-02 02:45:28 +01:00
|
|
|
memset(nulls, false, sizeof(nulls));
|
2006-12-23 01:43:13 +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
|
|
|
opfamilyoid = GetNewOidWithIndex(rel, OpfamilyOidIndexId,
|
|
|
|
Anum_pg_opfamily_oid);
|
|
|
|
values[Anum_pg_opfamily_oid - 1] = ObjectIdGetDatum(opfamilyoid);
|
2006-12-23 01:43:13 +01:00
|
|
|
values[Anum_pg_opfamily_opfmethod - 1] = ObjectIdGetDatum(amoid);
|
|
|
|
namestrcpy(&opfName, opfname);
|
|
|
|
values[Anum_pg_opfamily_opfname - 1] = NameGetDatum(&opfName);
|
|
|
|
values[Anum_pg_opfamily_opfnamespace - 1] = ObjectIdGetDatum(namespaceoid);
|
|
|
|
values[Anum_pg_opfamily_opfowner - 1] = ObjectIdGetDatum(GetUserId());
|
|
|
|
|
2008-11-02 02:45:28 +01:00
|
|
|
tup = heap_form_tuple(rel->rd_att, values, nulls);
|
2006-12-23 01:43:13 +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
|
|
|
CatalogTupleInsert(rel, tup);
|
2006-12-23 01:43:13 +01:00
|
|
|
|
|
|
|
heap_freetuple(tup);
|
|
|
|
|
|
|
|
/*
|
2016-04-14 05:33:31 +02:00
|
|
|
* Create dependencies for the opfamily proper.
|
2006-12-23 01:43:13 +01:00
|
|
|
*/
|
|
|
|
myself.classId = OperatorFamilyRelationId;
|
|
|
|
myself.objectId = opfamilyoid;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
2016-04-14 05:33:31 +02:00
|
|
|
/* dependency on access method */
|
|
|
|
referenced.classId = AccessMethodRelationId;
|
|
|
|
referenced.objectId = amoid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
|
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/* dependency on namespace */
|
|
|
|
referenced.classId = NamespaceRelationId;
|
|
|
|
referenced.objectId = namespaceoid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
|
|
|
|
/* dependency on owner */
|
|
|
|
recordDependencyOnOwner(OperatorFamilyRelationId, opfamilyoid, GetUserId());
|
|
|
|
|
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
|
|
|
|
2022-05-20 18:52:55 +02:00
|
|
|
/* Report the new operator family to possibly interested event triggers */
|
|
|
|
EventTriggerCollectSimpleCommand(myself, InvalidObjectAddress,
|
|
|
|
(Node *) stmt);
|
|
|
|
|
2010-11-25 17:48:49 +01:00
|
|
|
/* Post creation hook for new operator family */
|
2013-03-07 02:52:06 +01:00
|
|
|
InvokeObjectPostCreateHook(OperatorFamilyRelationId, opfamilyoid, 0);
|
2010-11-25 17:48:49 +01:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2006-12-23 01:43:13 +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;
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
|
|
|
|
2002-07-30 00:14:11 +02:00
|
|
|
/*
|
|
|
|
* DefineOpClass
|
|
|
|
* Define a new index operator class.
|
|
|
|
*/
|
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
|
2002-07-30 00:14:11 +02:00
|
|
|
DefineOpClass(CreateOpClassStmt *stmt)
|
|
|
|
{
|
|
|
|
char *opcname; /* name of opclass we're creating */
|
|
|
|
Oid amoid, /* our AM's oid */
|
|
|
|
typeoid, /* indexable datatype oid */
|
|
|
|
storageoid, /* storage datatype oid, if any */
|
|
|
|
namespaceoid, /* namespace to create opclass in */
|
2006-12-23 01:43:13 +01:00
|
|
|
opfamilyoid, /* oid of containing opfamily */
|
2002-07-30 00:14:11 +02:00
|
|
|
opclassoid; /* oid of opclass we create */
|
2006-12-18 19:56:29 +01:00
|
|
|
int maxOpNumber, /* amstrategies value */
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
optsProcNumber, /* amoptsprocnum value */
|
2006-12-18 19:56:29 +01:00
|
|
|
maxProcNumber; /* amsupport value */
|
2006-05-03 00:25:10 +02:00
|
|
|
bool amstorage; /* amstorage flag */
|
2006-12-23 01:43:13 +01:00
|
|
|
List *operators; /* OpFamilyMember list for operators */
|
|
|
|
List *procedures; /* OpFamilyMember list for support procs */
|
2004-05-26 06:41:50 +02:00
|
|
|
ListCell *l;
|
2002-07-30 00:14:11 +02:00
|
|
|
Relation rel;
|
|
|
|
HeapTuple tup;
|
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_am amform;
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
IndexAmRoutine *amroutine;
|
2002-07-30 00:14:11 +02:00
|
|
|
Datum values[Natts_pg_opclass];
|
2008-11-02 02:45:28 +01:00
|
|
|
bool nulls[Natts_pg_opclass];
|
2002-07-30 00:14:11 +02:00
|
|
|
AclResult aclresult;
|
|
|
|
NameData opcName;
|
|
|
|
ObjectAddress myself,
|
|
|
|
referenced;
|
|
|
|
|
|
|
|
/* Convert list of names to a name and namespace */
|
|
|
|
namespaceoid = QualifiedNameGetCreationNamespace(stmt->opclassname,
|
|
|
|
&opcname);
|
|
|
|
|
|
|
|
/* Check we have creation rights in target namespace */
|
|
|
|
aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
|
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_SCHEMA,
|
2003-08-01 02:15:26 +02:00
|
|
|
get_namespace_name(namespaceoid));
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
/* Get necessary info about access method */
|
2010-02-14 19:42:19 +01:00
|
|
|
tup = SearchSysCache1(AMNAME, CStringGetDatum(stmt->amname));
|
2002-07-30 00:14:11 +02:00
|
|
|
if (!HeapTupleIsValid(tup))
|
2003-07-19 01:20:33 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("access method \"%s\" does not exist",
|
|
|
|
stmt->amname)));
|
2002-07-30 00:14:11 +02: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
|
|
|
amform = (Form_pg_am) GETSTRUCT(tup);
|
|
|
|
amoid = amform->oid;
|
2016-08-14 00:31:14 +02:00
|
|
|
amroutine = GetIndexAmRoutineByAmId(amoid, false);
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
ReleaseSysCache(tup);
|
|
|
|
|
|
|
|
maxOpNumber = amroutine->amstrategies;
|
2006-12-18 19:56:29 +01:00
|
|
|
/* if amstrategies is zero, just enforce that op numbers fit in int16 */
|
|
|
|
if (maxOpNumber <= 0)
|
|
|
|
maxOpNumber = SHRT_MAX;
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
maxProcNumber = amroutine->amsupport;
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
optsProcNumber = amroutine->amoptsprocnum;
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
amstorage = amroutine->amstorage;
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
/* XXX Should we make any privilege check against the AM? */
|
|
|
|
|
2002-10-05 00:19:29 +02:00
|
|
|
/*
|
2006-01-13 19:10:25 +01:00
|
|
|
* The question of appropriate permissions for CREATE OPERATOR CLASS is
|
|
|
|
* interesting. Creating an opclass is tantamount to granting public
|
|
|
|
* execute access on the functions involved, since the index machinery
|
|
|
|
* generally does not check access permission before using the functions.
|
|
|
|
* A minimum expectation therefore is that the caller have execute
|
|
|
|
* privilege with grant option. Since we don't have a way to make the
|
|
|
|
* opclass go away if the grant option is revoked, we choose instead to
|
|
|
|
* require ownership of the functions. It's also not entirely clear what
|
|
|
|
* permissions should be required on the datatype, but ownership seems
|
|
|
|
* like a safe choice.
|
|
|
|
*
|
2002-10-05 00:19:29 +02:00
|
|
|
* Currently, we require superuser privileges to create an opclass. This
|
|
|
|
* seems necessary because we have no way to validate that the offered set
|
|
|
|
* of operators and functions are consistent with the AM's expectations.
|
|
|
|
* It would be nice to provide such a check someday, if it can be done
|
|
|
|
* without solving the halting problem :-(
|
2006-01-13 19:10:25 +01:00
|
|
|
*
|
|
|
|
* XXX re-enable NOT_USED code sections below if you remove this test.
|
2002-10-05 00:19:29 +02:00
|
|
|
*/
|
|
|
|
if (!superuser())
|
2003-07-19 01:20:33 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("must be superuser to create an operator class")));
|
2002-10-05 00:19:29 +02:00
|
|
|
|
2002-07-30 00:14:11 +02:00
|
|
|
/* Look up the datatype */
|
2010-10-25 20:40:46 +02:00
|
|
|
typeoid = typenameTypeId(NULL, stmt->datatype);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2002-10-05 00:19:29 +02:00
|
|
|
#ifdef NOT_USED
|
|
|
|
/* XXX this is unnecessary given the superuser check above */
|
2002-07-30 00:14:11 +02:00
|
|
|
/* Check we have ownership of the datatype */
|
|
|
|
if (!pg_type_ownercheck(typeoid, GetUserId()))
|
2012-06-15 21:55:03 +02:00
|
|
|
aclcheck_error_type(ACLCHECK_NOT_OWNER, typeoid);
|
2002-10-05 00:19:29 +02:00
|
|
|
#endif
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/*
|
|
|
|
* Look up the containing operator family, or create one if FAMILY option
|
|
|
|
* was omitted and there's not a match already.
|
|
|
|
*/
|
|
|
|
if (stmt->opfamilyname)
|
|
|
|
{
|
2010-08-05 17:25:36 +02:00
|
|
|
opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Lookup existing family of same name and namespace */
|
2010-02-14 19:42:19 +01:00
|
|
|
tup = SearchSysCache3(OPFAMILYAMNAMENSP,
|
|
|
|
ObjectIdGetDatum(amoid),
|
|
|
|
PointerGetDatum(opcname),
|
|
|
|
ObjectIdGetDatum(namespaceoid));
|
2006-12-23 01:43:13 +01:00
|
|
|
if (HeapTupleIsValid(tup))
|
|
|
|
{
|
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
|
|
|
opfamilyoid = ((Form_pg_opfamily) GETSTRUCT(tup))->oid;
|
2007-11-15 22:14:46 +01:00
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/*
|
|
|
|
* XXX given the superuser check above, there's no need for an
|
|
|
|
* ownership check here
|
|
|
|
*/
|
|
|
|
ReleaseSysCache(tup);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-05-20 18:52:55 +02:00
|
|
|
CreateOpFamilyStmt *opfstmt;
|
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 tmpAddr;
|
|
|
|
|
2022-05-20 18:52:55 +02:00
|
|
|
opfstmt = makeNode(CreateOpFamilyStmt);
|
|
|
|
opfstmt->opfamilyname = stmt->opclassname;
|
|
|
|
opfstmt->amname = stmt->amname;
|
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/*
|
|
|
|
* Create it ... again no need for more permissions ...
|
|
|
|
*/
|
2022-05-20 18:52:55 +02:00
|
|
|
tmpAddr = CreateOpFamily(opfstmt, opcname, namespaceoid, amoid);
|
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
|
|
|
opfamilyoid = tmpAddr.objectId;
|
2006-12-23 01:43:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
operators = NIL;
|
|
|
|
procedures = NIL;
|
|
|
|
|
2002-07-30 00:14:11 +02:00
|
|
|
/* Storage datatype is optional */
|
|
|
|
storageoid = InvalidOid;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Scan the "items" list to obtain additional info.
|
|
|
|
*/
|
2003-11-12 22:15:59 +01:00
|
|
|
foreach(l, stmt->items)
|
2002-07-30 00:14:11 +02:00
|
|
|
{
|
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
|
|
|
CreateOpClassItem *item = lfirst_node(CreateOpClassItem, l);
|
2002-07-30 00:14:11 +02:00
|
|
|
Oid operOid;
|
|
|
|
Oid funcOid;
|
2010-11-24 20:20:39 +01:00
|
|
|
Oid sortfamilyOid;
|
2006-12-23 01:43:13 +01:00
|
|
|
OpFamilyMember *member;
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
switch (item->itemtype)
|
|
|
|
{
|
|
|
|
case OPCLASS_ITEM_OPERATOR:
|
2006-12-18 19:56:29 +01:00
|
|
|
if (item->number <= 0 || item->number > maxOpNumber)
|
2003-07-19 01:20:33 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("invalid operator number %d,"
|
|
|
|
" must be between 1 and %d",
|
2006-12-18 19:56:29 +01:00
|
|
|
item->number, maxOpNumber)));
|
2016-12-28 18:00:00 +01:00
|
|
|
if (item->name->objargs != NIL)
|
|
|
|
operOid = LookupOperWithArgs(item->name, false);
|
2002-07-30 00:14:11 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Default to binary op on input datatype */
|
2016-12-28 18:00:00 +01:00
|
|
|
operOid = LookupOperName(NULL, item->name->objname,
|
2006-03-14 23:48:25 +01:00
|
|
|
typeoid, typeoid,
|
|
|
|
false, -1);
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
2006-01-13 19:10:25 +01:00
|
|
|
|
2010-11-24 20:20:39 +01:00
|
|
|
if (item->order_family)
|
|
|
|
sortfamilyOid = get_opfamily_oid(BTREE_AM_OID,
|
|
|
|
item->order_family,
|
|
|
|
false);
|
|
|
|
else
|
|
|
|
sortfamilyOid = InvalidOid;
|
|
|
|
|
2006-01-13 19:10:25 +01:00
|
|
|
#ifdef NOT_USED
|
|
|
|
/* XXX this is unnecessary given the superuser check above */
|
|
|
|
/* Caller must own operator and its underlying function */
|
|
|
|
if (!pg_oper_ownercheck(operOid, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR,
|
2006-01-13 19:10:25 +01:00
|
|
|
get_opname(operOid));
|
2002-07-30 00:14:11 +02:00
|
|
|
funcOid = get_opcode(operOid);
|
2006-01-13 19:10:25 +01:00
|
|
|
if (!pg_proc_ownercheck(funcOid, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION,
|
2003-08-01 02:15:26 +02:00
|
|
|
get_func_name(funcOid));
|
2006-01-13 19:10:25 +01:00
|
|
|
#endif
|
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
/* Save the info */
|
2006-12-23 01:43:13 +01:00
|
|
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
2020-08-01 23:12:47 +02:00
|
|
|
member->is_func = false;
|
2003-11-12 22:15:59 +01:00
|
|
|
member->object = operOid;
|
|
|
|
member->number = item->number;
|
2010-11-24 20:20:39 +01:00
|
|
|
member->sortfamily = sortfamilyOid;
|
2006-12-23 01:43:13 +01:00
|
|
|
assignOperTypes(member, amoid, typeoid);
|
2020-08-01 23:12:47 +02:00
|
|
|
addFamilyMember(&operators, member);
|
2002-07-30 00:14:11 +02:00
|
|
|
break;
|
|
|
|
case OPCLASS_ITEM_FUNCTION:
|
2006-12-18 19:56:29 +01:00
|
|
|
if (item->number <= 0 || item->number > maxProcNumber)
|
2003-07-19 01:20:33 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("invalid function number %d,"
|
2003-07-19 01:20:33 +02:00
|
|
|
" must be between 1 and %d",
|
2006-12-18 19:56:29 +01:00
|
|
|
item->number, maxProcNumber)));
|
2017-11-30 14:46:13 +01:00
|
|
|
funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false);
|
2006-01-13 19:10:25 +01:00
|
|
|
#ifdef NOT_USED
|
|
|
|
/* XXX this is unnecessary given the superuser check above */
|
|
|
|
/* Caller must own function */
|
|
|
|
if (!pg_proc_ownercheck(funcOid, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION,
|
2003-08-01 02:15:26 +02:00
|
|
|
get_func_name(funcOid));
|
2006-01-13 19:10:25 +01:00
|
|
|
#endif
|
2003-11-12 22:15:59 +01:00
|
|
|
/* Save the info */
|
2006-12-23 01:43:13 +01:00
|
|
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
2020-08-01 23:12:47 +02:00
|
|
|
member->is_func = true;
|
2003-11-12 22:15:59 +01:00
|
|
|
member->object = funcOid;
|
|
|
|
member->number = item->number;
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
/* allow overriding of the function's actual arg types */
|
|
|
|
if (item->class_args)
|
|
|
|
processTypesSpec(item->class_args,
|
|
|
|
&member->lefttype, &member->righttype);
|
|
|
|
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
assignProcTypes(member, amoid, typeoid, optsProcNumber);
|
2020-08-01 23:12:47 +02:00
|
|
|
addFamilyMember(&procedures, member);
|
2002-07-30 00:14:11 +02:00
|
|
|
break;
|
|
|
|
case OPCLASS_ITEM_STORAGETYPE:
|
|
|
|
if (OidIsValid(storageoid))
|
2003-07-19 01:20:33 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("storage type specified more than once")));
|
2010-10-25 20:40:46 +02:00
|
|
|
storageoid = typenameTypeId(NULL, item->storedtype);
|
2006-01-13 19:10:25 +01:00
|
|
|
|
|
|
|
#ifdef NOT_USED
|
|
|
|
/* XXX this is unnecessary given the superuser check above */
|
|
|
|
/* Check we have ownership of the datatype */
|
|
|
|
if (!pg_type_ownercheck(storageoid, GetUserId()))
|
2012-06-15 21:55:03 +02:00
|
|
|
aclcheck_error_type(ACLCHECK_NOT_OWNER, storageoid);
|
2006-01-13 19:10:25 +01:00
|
|
|
#endif
|
2002-07-30 00:14:11 +02:00
|
|
|
break;
|
|
|
|
default:
|
2003-07-19 01:20:33 +02:00
|
|
|
elog(ERROR, "unrecognized item type: %d", item->itemtype);
|
2002-07-30 00:14:11 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If storagetype is specified, make sure it's legal.
|
|
|
|
*/
|
|
|
|
if (OidIsValid(storageoid))
|
|
|
|
{
|
|
|
|
/* Just drop the spec if same as column datatype */
|
|
|
|
if (storageoid == typeoid)
|
|
|
|
storageoid = InvalidOid;
|
2006-05-03 00:25:10 +02:00
|
|
|
else if (!amstorage)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
Wording cleanup for error messages. Also change can't -> cannot.
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 20:10:30 +01:00
|
|
|
errmsg("storage type cannot be different from data type for access method \"%s\"",
|
2006-05-03 00:25:10 +02:00
|
|
|
stmt->amname)));
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(OperatorClassRelationId, RowExclusiveLock);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure there is no existing opclass of this name (this is just to
|
|
|
|
* give a more friendly error message than "duplicate key").
|
|
|
|
*/
|
2010-02-14 19:42:19 +01:00
|
|
|
if (SearchSysCacheExists3(CLAAMNAMENSP,
|
|
|
|
ObjectIdGetDatum(amoid),
|
|
|
|
CStringGetDatum(opcname),
|
|
|
|
ObjectIdGetDatum(namespaceoid)))
|
2003-07-19 01:20:33 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
2003-07-20 23:56:35 +02:00
|
|
|
errmsg("operator class \"%s\" for access method \"%s\" already exists",
|
2003-07-19 01:20:33 +02:00
|
|
|
opcname, stmt->amname)));
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we are creating a default opclass, check there isn't one already.
|
2003-08-17 21:58:06 +02:00
|
|
|
* (Note we do not restrict this test to visible opclasses; this ensures
|
|
|
|
* that typcache.c can find unique solutions to its questions.)
|
2002-07-30 00:14:11 +02:00
|
|
|
*/
|
|
|
|
if (stmt->isDefault)
|
|
|
|
{
|
|
|
|
ScanKeyData skey[1];
|
|
|
|
SysScanDesc scan;
|
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
ScanKeyInit(&skey[0],
|
2006-12-23 01:43:13 +01:00
|
|
|
Anum_pg_opclass_opcmethod,
|
2003-11-12 22:15:59 +01:00
|
|
|
BTEqualStrategyNumber, F_OIDEQ,
|
|
|
|
ObjectIdGetDatum(amoid));
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2005-04-14 22:03:27 +02:00
|
|
|
scan = systable_beginscan(rel, OpclassAmNameNspIndexId, true,
|
Use an MVCC snapshot, rather than SnapshotNow, for catalog scans.
SnapshotNow scans have the undesirable property that, in the face of
concurrent updates, the scan can fail to see either the old or the new
versions of the row. In many cases, we work around this by requiring
DDL operations to hold AccessExclusiveLock on the object being
modified; in some cases, the existing locking is inadequate and random
failures occur as a result. This commit doesn't change anything
related to locking, but will hopefully pave the way to allowing lock
strength reductions in the future.
The major issue has held us back from making this change in the past
is that taking an MVCC snapshot is significantly more expensive than
using a static special snapshot such as SnapshotNow. However, testing
of various worst-case scenarios reveals that this problem is not
severe except under fairly extreme workloads. To mitigate those
problems, we avoid retaking the MVCC snapshot for each new scan;
instead, we take a new snapshot only when invalidation messages have
been processed. The catcache machinery already requires that
invalidation messages be sent before releasing the related heavyweight
lock; else other backends might rely on locally-cached data rather
than scanning the catalog at all. Thus, making snapshot reuse
dependent on the same guarantees shouldn't break anything that wasn't
already subtly broken.
Patch by me. Review by Michael Paquier and Andres Freund.
2013-07-02 15:47:01 +02:00
|
|
|
NULL, 1, skey);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
|
|
|
{
|
|
|
|
Form_pg_opclass opclass = (Form_pg_opclass) GETSTRUCT(tup);
|
|
|
|
|
|
|
|
if (opclass->opcintype == typeoid && opclass->opcdefault)
|
2003-07-19 01:20:33 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
2003-09-26 17:27:37 +02:00
|
|
|
errmsg("could not make operator class \"%s\" be default for type %s",
|
2003-07-19 01:20:33 +02:00
|
|
|
opcname,
|
|
|
|
TypeNameToString(stmt->datatype)),
|
2003-09-26 17:27:37 +02:00
|
|
|
errdetail("Operator class \"%s\" already is the default.",
|
2003-07-19 01:20:33 +02:00
|
|
|
NameStr(opclass->opcname))));
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
systable_endscan(scan);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Okay, let's create the pg_opclass entry.
|
|
|
|
*/
|
2006-12-23 01:43:13 +01:00
|
|
|
memset(values, 0, sizeof(values));
|
2008-11-02 02:45:28 +01:00
|
|
|
memset(nulls, false, sizeof(nulls));
|
2002-07-30 00:14:11 +02: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
|
|
|
opclassoid = GetNewOidWithIndex(rel, OpclassOidIndexId,
|
|
|
|
Anum_pg_opclass_oid);
|
|
|
|
values[Anum_pg_opclass_oid - 1] = ObjectIdGetDatum(opclassoid);
|
2006-12-23 01:43:13 +01:00
|
|
|
values[Anum_pg_opclass_opcmethod - 1] = ObjectIdGetDatum(amoid);
|
2002-07-30 00:14:11 +02:00
|
|
|
namestrcpy(&opcName, opcname);
|
2006-12-23 01:43:13 +01:00
|
|
|
values[Anum_pg_opclass_opcname - 1] = NameGetDatum(&opcName);
|
|
|
|
values[Anum_pg_opclass_opcnamespace - 1] = ObjectIdGetDatum(namespaceoid);
|
|
|
|
values[Anum_pg_opclass_opcowner - 1] = ObjectIdGetDatum(GetUserId());
|
|
|
|
values[Anum_pg_opclass_opcfamily - 1] = ObjectIdGetDatum(opfamilyoid);
|
|
|
|
values[Anum_pg_opclass_opcintype - 1] = ObjectIdGetDatum(typeoid);
|
|
|
|
values[Anum_pg_opclass_opcdefault - 1] = BoolGetDatum(stmt->isDefault);
|
|
|
|
values[Anum_pg_opclass_opckeytype - 1] = ObjectIdGetDatum(storageoid);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2008-11-02 02:45:28 +01:00
|
|
|
tup = heap_form_tuple(rel->rd_att, values, nulls);
|
2002-07-30 00:14:11 +02: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
|
|
|
CatalogTupleInsert(rel, tup);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
heap_freetuple(tup);
|
|
|
|
|
2020-08-01 23:12:47 +02:00
|
|
|
/*
|
|
|
|
* Now that we have the opclass OID, set up default dependency info for
|
|
|
|
* the pg_amop and pg_amproc entries. Historically, CREATE OPERATOR CLASS
|
|
|
|
* has created hard dependencies on the opclass, so that's what we use.
|
|
|
|
*/
|
|
|
|
foreach(l, operators)
|
|
|
|
{
|
|
|
|
OpFamilyMember *op = (OpFamilyMember *) lfirst(l);
|
|
|
|
|
|
|
|
op->ref_is_hard = true;
|
|
|
|
op->ref_is_family = false;
|
|
|
|
op->refobjid = opclassoid;
|
|
|
|
}
|
|
|
|
foreach(l, procedures)
|
|
|
|
{
|
|
|
|
OpFamilyMember *proc = (OpFamilyMember *) lfirst(l);
|
|
|
|
|
|
|
|
proc->ref_is_hard = true;
|
|
|
|
proc->ref_is_family = false;
|
|
|
|
proc->refobjid = opclassoid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Let the index AM editorialize on the dependency choices. It could also
|
|
|
|
* do further validation on the operators and functions, if it likes.
|
|
|
|
*/
|
|
|
|
if (amroutine->amadjustmembers)
|
|
|
|
amroutine->amadjustmembers(opfamilyoid,
|
|
|
|
opclassoid,
|
|
|
|
operators,
|
|
|
|
procedures);
|
|
|
|
|
2002-07-30 00:14:11 +02:00
|
|
|
/*
|
|
|
|
* Now add tuples to pg_amop and pg_amproc tying in the operators and
|
2006-12-23 01:43:13 +01:00
|
|
|
* functions. Dependencies on them are inserted, too.
|
2002-07-30 00:14:11 +02:00
|
|
|
*/
|
2007-01-23 06:07:18 +01:00
|
|
|
storeOperators(stmt->opfamilyname, amoid, opfamilyoid,
|
2020-08-01 23:12:47 +02:00
|
|
|
operators, false);
|
2007-01-23 06:07:18 +01:00
|
|
|
storeProcedures(stmt->opfamilyname, amoid, opfamilyoid,
|
2020-08-01 23:12:47 +02:00
|
|
|
procedures, false);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
/* let event triggers know what happened */
|
|
|
|
EventTriggerCollectCreateOpClass(stmt, opclassoid, operators, procedures);
|
|
|
|
|
2002-07-30 00:14:11 +02:00
|
|
|
/*
|
2016-04-14 05:33:31 +02:00
|
|
|
* Create dependencies for the opclass proper. Note: we do not need a
|
|
|
|
* dependency link to the AM, because that exists through the opfamily.
|
2002-07-30 00:14:11 +02:00
|
|
|
*/
|
2005-04-14 22:03:27 +02:00
|
|
|
myself.classId = OperatorClassRelationId;
|
2002-07-30 00:14:11 +02:00
|
|
|
myself.objectId = opclassoid;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
|
|
|
/* dependency on namespace */
|
2005-04-14 22:03:27 +02:00
|
|
|
referenced.classId = NamespaceRelationId;
|
2002-07-30 00:14:11 +02:00
|
|
|
referenced.objectId = namespaceoid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/* dependency on opfamily */
|
|
|
|
referenced.classId = OperatorFamilyRelationId;
|
|
|
|
referenced.objectId = opfamilyoid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_AUTO);
|
|
|
|
|
2002-07-30 00:14:11 +02:00
|
|
|
/* dependency on indexed datatype */
|
2005-04-14 03:38:22 +02:00
|
|
|
referenced.classId = TypeRelationId;
|
2002-07-30 00:14:11 +02:00
|
|
|
referenced.objectId = typeoid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
|
|
|
|
/* dependency on storage datatype */
|
|
|
|
if (OidIsValid(storageoid))
|
|
|
|
{
|
2005-04-14 03:38:22 +02:00
|
|
|
referenced.classId = TypeRelationId;
|
2002-07-30 00:14:11 +02:00
|
|
|
referenced.objectId = storageoid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
|
|
|
}
|
|
|
|
|
2005-07-07 22:40:02 +02:00
|
|
|
/* dependency on owner */
|
|
|
|
recordDependencyOnOwner(OperatorClassRelationId, opclassoid, GetUserId());
|
|
|
|
|
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 operator class */
|
2013-03-07 02:52:06 +01:00
|
|
|
InvokeObjectPostCreateHook(OperatorClassRelationId, opclassoid, 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;
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
/*
|
2007-01-23 06:07:18 +01:00
|
|
|
* DefineOpFamily
|
|
|
|
* Define a new index operator family.
|
2003-11-12 22:15:59 +01:00
|
|
|
*/
|
Change many routines to return ObjectAddress rather than OID
The changed routines are mostly those that can be directly called by
ProcessUtilitySlow; the intention is to make the affected object
information more precise, in support for future event trigger changes.
Originally it was envisioned that the OID of the affected object would
be enough, and in most cases that is correct, but upon actually
implementing the event trigger changes it turned out that ObjectAddress
is more widely useful.
Additionally, some command execution routines grew an output argument
that's an object address which provides further info about the executed
command. To wit:
* for ALTER DOMAIN / ADD CONSTRAINT, it corresponds to the address of
the new constraint
* for ALTER OBJECT / SET SCHEMA, it corresponds to the address of the
schema that originally contained the object.
* for ALTER EXTENSION {ADD, DROP} OBJECT, it corresponds to the address
of the object added to or dropped from the extension.
There's no user-visible change in this commit, and no functional change
either.
Discussion: 20150218213255.GC6717@tamriel.snowman.net
Reviewed-By: Stephen Frost, Andres Freund
2015-03-03 18:10:50 +01:00
|
|
|
ObjectAddress
|
2007-01-23 06:07:18 +01:00
|
|
|
DefineOpFamily(CreateOpFamilyStmt *stmt)
|
2003-11-12 22:15:59 +01:00
|
|
|
{
|
2007-01-23 06:07:18 +01:00
|
|
|
char *opfname; /* name of opfamily we're creating */
|
|
|
|
Oid amoid, /* our AM's oid */
|
2010-07-16 02:13:23 +02:00
|
|
|
namespaceoid; /* namespace to create opfamily in */
|
2007-01-23 06:07:18 +01:00
|
|
|
AclResult aclresult;
|
2003-11-12 22:15:59 +01:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/* Convert list of names to a name and namespace */
|
|
|
|
namespaceoid = QualifiedNameGetCreationNamespace(stmt->opfamilyname,
|
|
|
|
&opfname);
|
|
|
|
|
|
|
|
/* Check we have creation rights in target namespace */
|
|
|
|
aclresult = pg_namespace_aclcheck(namespaceoid, GetUserId(), ACL_CREATE);
|
|
|
|
if (aclresult != ACLCHECK_OK)
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(aclresult, OBJECT_SCHEMA,
|
2007-01-23 06:07:18 +01:00
|
|
|
get_namespace_name(namespaceoid));
|
|
|
|
|
2010-08-05 16:45:09 +02:00
|
|
|
/* Get access method OID, throwing an error if it doesn't exist. */
|
2016-03-24 03:01:35 +01:00
|
|
|
amoid = get_index_am_oid(stmt->amname, false);
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
/* XXX Should we make any privilege check against the AM? */
|
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
/*
|
2007-01-23 06:07:18 +01:00
|
|
|
* Currently, we require superuser privileges to create an opfamily. See
|
|
|
|
* comments in DefineOpClass.
|
2003-11-12 22:15:59 +01:00
|
|
|
*/
|
2007-01-23 06:07:18 +01:00
|
|
|
if (!superuser())
|
2003-11-12 22:15:59 +01:00
|
|
|
ereport(ERROR,
|
2007-01-23 06:07:18 +01:00
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("must be superuser to create an operator family")));
|
|
|
|
|
2010-07-16 02:13:23 +02:00
|
|
|
/* Insert pg_opfamily catalog entry */
|
2022-05-20 18:52:55 +02:00
|
|
|
return CreateOpFamily(stmt, opfname, namespaceoid, amoid);
|
2003-11-12 22:15:59 +01:00
|
|
|
}
|
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
/*
|
2007-01-23 06:07:18 +01:00
|
|
|
* AlterOpFamily
|
|
|
|
* Add or remove operators/procedures within an existing operator family.
|
|
|
|
*
|
|
|
|
* Note: this implements only ALTER OPERATOR FAMILY ... ADD/DROP. Some
|
|
|
|
* other commands called ALTER OPERATOR FAMILY exist, but go through
|
|
|
|
* different code paths.
|
2003-11-12 22:15:59 +01:00
|
|
|
*/
|
2012-12-29 13:55:37 +01:00
|
|
|
Oid
|
2007-01-23 06:07:18 +01:00
|
|
|
AlterOpFamily(AlterOpFamilyStmt *stmt)
|
2003-11-12 22:15:59 +01:00
|
|
|
{
|
2007-01-23 06:07:18 +01:00
|
|
|
Oid amoid, /* our AM's oid */
|
|
|
|
opfamilyoid; /* oid of opfamily */
|
|
|
|
int maxOpNumber, /* amstrategies value */
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
optsProcNumber, /* amopclassopts value */
|
2007-01-23 06:07:18 +01:00
|
|
|
maxProcNumber; /* amsupport value */
|
|
|
|
HeapTuple tup;
|
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_am amform;
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
IndexAmRoutine *amroutine;
|
2003-11-12 22:15:59 +01:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/* Get necessary info about access method */
|
2010-02-14 19:42:19 +01:00
|
|
|
tup = SearchSysCache1(AMNAME, CStringGetDatum(stmt->amname));
|
2007-01-23 06:07:18 +01:00
|
|
|
if (!HeapTupleIsValid(tup))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("access method \"%s\" does not exist",
|
|
|
|
stmt->amname)));
|
|
|
|
|
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
|
|
|
amform = (Form_pg_am) GETSTRUCT(tup);
|
|
|
|
amoid = amform->oid;
|
2016-08-14 00:31:14 +02:00
|
|
|
amroutine = GetIndexAmRoutineByAmId(amoid, false);
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
ReleaseSysCache(tup);
|
|
|
|
|
|
|
|
maxOpNumber = amroutine->amstrategies;
|
2007-01-23 06:07:18 +01:00
|
|
|
/* if amstrategies is zero, just enforce that op numbers fit in int16 */
|
|
|
|
if (maxOpNumber <= 0)
|
|
|
|
maxOpNumber = SHRT_MAX;
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
maxProcNumber = amroutine->amsupport;
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
optsProcNumber = amroutine->amoptsprocnum;
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
/* XXX Should we make any privilege check against the AM? */
|
|
|
|
|
|
|
|
/* Look up the opfamily */
|
2010-08-05 17:25:36 +02:00
|
|
|
opfamilyoid = get_opfamily_oid(amoid, stmt->opfamilyname, false);
|
2004-08-29 07:07:03 +02:00
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
/*
|
2007-01-23 06:07:18 +01:00
|
|
|
* Currently, we require superuser privileges to alter an opfamily.
|
|
|
|
*
|
|
|
|
* XXX re-enable NOT_USED code sections below if you remove this test.
|
2003-11-12 22:15:59 +01:00
|
|
|
*/
|
2007-01-23 06:07:18 +01:00
|
|
|
if (!superuser())
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
|
|
|
errmsg("must be superuser to alter an operator family")));
|
2006-12-23 01:43:13 +01:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/*
|
|
|
|
* ADD and DROP cases need separate code from here on down.
|
|
|
|
*/
|
|
|
|
if (stmt->isDrop)
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
AlterOpFamilyDrop(stmt, amoid, opfamilyoid,
|
|
|
|
maxOpNumber, maxProcNumber, stmt->items);
|
2003-11-12 22:15:59 +01:00
|
|
|
else
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
AlterOpFamilyAdd(stmt, amoid, opfamilyoid,
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
maxOpNumber, maxProcNumber, optsProcNumber,
|
|
|
|
stmt->items);
|
2012-12-29 13:55:37 +01:00
|
|
|
|
|
|
|
return opfamilyoid;
|
2003-11-12 22:15:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-01-23 06:07:18 +01:00
|
|
|
* ADD part of ALTER OP FAMILY
|
2003-11-12 22:15:59 +01:00
|
|
|
*/
|
|
|
|
static void
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
AlterOpFamilyAdd(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
int maxOpNumber, int maxProcNumber, int optsProcNumber,
|
|
|
|
List *items)
|
2003-11-12 22:15:59 +01:00
|
|
|
{
|
2020-08-01 23:12:47 +02:00
|
|
|
IndexAmRoutine *amroutine = GetIndexAmRoutineByAmId(amoid, false);
|
2007-01-23 06:07:18 +01:00
|
|
|
List *operators; /* OpFamilyMember list for operators */
|
|
|
|
List *procedures; /* OpFamilyMember list for support procs */
|
2004-05-26 06:41:50 +02:00
|
|
|
ListCell *l;
|
2003-11-12 22:15:59 +01:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
operators = NIL;
|
|
|
|
procedures = NIL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Scan the "items" list to obtain additional info.
|
|
|
|
*/
|
|
|
|
foreach(l, items)
|
2003-11-12 22:15:59 +01:00
|
|
|
{
|
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
|
|
|
CreateOpClassItem *item = lfirst_node(CreateOpClassItem, l);
|
2007-01-23 06:07:18 +01:00
|
|
|
Oid operOid;
|
|
|
|
Oid funcOid;
|
2010-11-24 20:20:39 +01:00
|
|
|
Oid sortfamilyOid;
|
2007-01-23 06:07:18 +01:00
|
|
|
OpFamilyMember *member;
|
2003-11-12 22:15:59 +01:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
switch (item->itemtype)
|
2003-11-12 22:15:59 +01:00
|
|
|
{
|
2007-01-23 06:07:18 +01:00
|
|
|
case OPCLASS_ITEM_OPERATOR:
|
|
|
|
if (item->number <= 0 || item->number > maxOpNumber)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("invalid operator number %d,"
|
|
|
|
" must be between 1 and %d",
|
|
|
|
item->number, maxOpNumber)));
|
2016-12-28 18:00:00 +01:00
|
|
|
if (item->name->objargs != NIL)
|
|
|
|
operOid = LookupOperWithArgs(item->name, false);
|
2007-01-23 06:07:18 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
|
|
errmsg("operator argument types must be specified in ALTER OPERATOR FAMILY")));
|
|
|
|
operOid = InvalidOid; /* keep compiler quiet */
|
|
|
|
}
|
|
|
|
|
2010-11-24 20:20:39 +01:00
|
|
|
if (item->order_family)
|
|
|
|
sortfamilyOid = get_opfamily_oid(BTREE_AM_OID,
|
|
|
|
item->order_family,
|
|
|
|
false);
|
|
|
|
else
|
|
|
|
sortfamilyOid = InvalidOid;
|
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
#ifdef NOT_USED
|
|
|
|
/* XXX this is unnecessary given the superuser check above */
|
|
|
|
/* Caller must own operator and its underlying function */
|
|
|
|
if (!pg_oper_ownercheck(operOid, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_OPERATOR,
|
2007-01-23 06:07:18 +01:00
|
|
|
get_opname(operOid));
|
|
|
|
funcOid = get_opcode(operOid);
|
|
|
|
if (!pg_proc_ownercheck(funcOid, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION,
|
2007-01-23 06:07:18 +01:00
|
|
|
get_func_name(funcOid));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Save the info */
|
|
|
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
2020-08-01 23:12:47 +02:00
|
|
|
member->is_func = false;
|
2007-01-23 06:07:18 +01:00
|
|
|
member->object = operOid;
|
|
|
|
member->number = item->number;
|
2010-11-24 20:20:39 +01:00
|
|
|
member->sortfamily = sortfamilyOid;
|
2020-08-01 23:12:47 +02:00
|
|
|
/* We can set up dependency fields immediately */
|
|
|
|
/* Historically, ALTER ADD has created soft dependencies */
|
|
|
|
member->ref_is_hard = false;
|
|
|
|
member->ref_is_family = true;
|
|
|
|
member->refobjid = opfamilyoid;
|
2007-01-23 06:07:18 +01:00
|
|
|
assignOperTypes(member, amoid, InvalidOid);
|
2020-08-01 23:12:47 +02:00
|
|
|
addFamilyMember(&operators, member);
|
2007-01-23 06:07:18 +01:00
|
|
|
break;
|
|
|
|
case OPCLASS_ITEM_FUNCTION:
|
|
|
|
if (item->number <= 0 || item->number > maxProcNumber)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("invalid function number %d,"
|
2007-01-23 06:07:18 +01:00
|
|
|
" must be between 1 and %d",
|
|
|
|
item->number, maxProcNumber)));
|
2017-11-30 14:46:13 +01:00
|
|
|
funcOid = LookupFuncWithArgs(OBJECT_FUNCTION, item->name, false);
|
2007-01-23 06:07:18 +01:00
|
|
|
#ifdef NOT_USED
|
|
|
|
/* XXX this is unnecessary given the superuser check above */
|
|
|
|
/* Caller must own function */
|
|
|
|
if (!pg_proc_ownercheck(funcOid, GetUserId()))
|
2017-12-02 15:26:34 +01:00
|
|
|
aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION,
|
2007-01-23 06:07:18 +01:00
|
|
|
get_func_name(funcOid));
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Save the info */
|
|
|
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
2020-08-01 23:12:47 +02:00
|
|
|
member->is_func = true;
|
2007-01-23 06:07:18 +01:00
|
|
|
member->object = funcOid;
|
|
|
|
member->number = item->number;
|
2020-08-01 23:12:47 +02:00
|
|
|
/* We can set up dependency fields immediately */
|
|
|
|
/* Historically, ALTER ADD has created soft dependencies */
|
|
|
|
member->ref_is_hard = false;
|
|
|
|
member->ref_is_family = true;
|
|
|
|
member->refobjid = opfamilyoid;
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
/* allow overriding of the function's actual arg types */
|
|
|
|
if (item->class_args)
|
|
|
|
processTypesSpec(item->class_args,
|
|
|
|
&member->lefttype, &member->righttype);
|
|
|
|
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
assignProcTypes(member, amoid, InvalidOid, optsProcNumber);
|
2020-08-01 23:12:47 +02:00
|
|
|
addFamilyMember(&procedures, member);
|
2007-01-23 06:07:18 +01:00
|
|
|
break;
|
|
|
|
case OPCLASS_ITEM_STORAGETYPE:
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
Wording cleanup for error messages. Also change can't -> cannot.
Standard English uses "may", "can", and "might" in different ways:
may - permission, "You may borrow my rake."
can - ability, "I can lift that log."
might - possibility, "It might rain today."
Unfortunately, in conversational English, their use is often mixed, as
in, "You may use this variable to do X", when in fact, "can" is a better
choice. Similarly, "It may crash" is better stated, "It might crash".
2007-02-01 20:10:30 +01:00
|
|
|
errmsg("STORAGE cannot be specified in ALTER OPERATOR FAMILY")));
|
2007-01-23 06:07:18 +01:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized item type: %d", item->itemtype);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-01 23:12:47 +02:00
|
|
|
/*
|
|
|
|
* Let the index AM editorialize on the dependency choices. It could also
|
|
|
|
* do further validation on the operators and functions, if it likes.
|
|
|
|
*/
|
|
|
|
if (amroutine->amadjustmembers)
|
|
|
|
amroutine->amadjustmembers(opfamilyoid,
|
|
|
|
InvalidOid, /* no specific opclass */
|
|
|
|
operators,
|
|
|
|
procedures);
|
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/*
|
|
|
|
* Add tuples to pg_amop and pg_amproc tying in the operators and
|
|
|
|
* functions. Dependencies on them are inserted, too.
|
|
|
|
*/
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
storeOperators(stmt->opfamilyname, amoid, opfamilyoid,
|
2020-08-01 23:12:47 +02:00
|
|
|
operators, true);
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
storeProcedures(stmt->opfamilyname, amoid, opfamilyoid,
|
2020-08-01 23:12:47 +02:00
|
|
|
procedures, true);
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
|
|
|
|
/* make information available to event triggers */
|
|
|
|
EventTriggerCollectAlterOpFam(stmt, opfamilyoid,
|
|
|
|
operators, procedures);
|
2007-01-23 06:07:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* DROP part of ALTER OP FAMILY
|
|
|
|
*/
|
|
|
|
static void
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
AlterOpFamilyDrop(AlterOpFamilyStmt *stmt, Oid amoid, Oid opfamilyoid,
|
|
|
|
int maxOpNumber, int maxProcNumber, List *items)
|
2007-01-23 06:07:18 +01:00
|
|
|
{
|
|
|
|
List *operators; /* OpFamilyMember list for operators */
|
|
|
|
List *procedures; /* OpFamilyMember list for support procs */
|
|
|
|
ListCell *l;
|
|
|
|
|
|
|
|
operators = NIL;
|
|
|
|
procedures = NIL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Scan the "items" list to obtain additional info.
|
|
|
|
*/
|
|
|
|
foreach(l, items)
|
|
|
|
{
|
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
|
|
|
CreateOpClassItem *item = lfirst_node(CreateOpClassItem, l);
|
2007-01-23 06:07:18 +01:00
|
|
|
Oid lefttype,
|
|
|
|
righttype;
|
|
|
|
OpFamilyMember *member;
|
|
|
|
|
|
|
|
switch (item->itemtype)
|
|
|
|
{
|
|
|
|
case OPCLASS_ITEM_OPERATOR:
|
|
|
|
if (item->number <= 0 || item->number > maxOpNumber)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("invalid operator number %d,"
|
|
|
|
" must be between 1 and %d",
|
|
|
|
item->number, maxOpNumber)));
|
2016-12-28 18:00:00 +01:00
|
|
|
processTypesSpec(item->class_args, &lefttype, &righttype);
|
2007-01-23 06:07:18 +01:00
|
|
|
/* Save the info */
|
|
|
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
2020-08-01 23:12:47 +02:00
|
|
|
member->is_func = false;
|
2007-01-23 06:07:18 +01:00
|
|
|
member->number = item->number;
|
|
|
|
member->lefttype = lefttype;
|
|
|
|
member->righttype = righttype;
|
2020-08-01 23:12:47 +02:00
|
|
|
addFamilyMember(&operators, member);
|
2007-01-23 06:07:18 +01:00
|
|
|
break;
|
|
|
|
case OPCLASS_ITEM_FUNCTION:
|
|
|
|
if (item->number <= 0 || item->number > maxProcNumber)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("invalid function number %d,"
|
2007-01-23 06:07:18 +01:00
|
|
|
" must be between 1 and %d",
|
|
|
|
item->number, maxProcNumber)));
|
2016-12-28 18:00:00 +01:00
|
|
|
processTypesSpec(item->class_args, &lefttype, &righttype);
|
2007-01-23 06:07:18 +01:00
|
|
|
/* Save the info */
|
|
|
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
2020-08-01 23:12:47 +02:00
|
|
|
member->is_func = true;
|
2007-01-23 06:07:18 +01:00
|
|
|
member->number = item->number;
|
|
|
|
member->lefttype = lefttype;
|
|
|
|
member->righttype = righttype;
|
2020-08-01 23:12:47 +02:00
|
|
|
addFamilyMember(&procedures, member);
|
2007-01-23 06:07:18 +01:00
|
|
|
break;
|
|
|
|
case OPCLASS_ITEM_STORAGETYPE:
|
|
|
|
/* grammar prevents this from appearing */
|
|
|
|
default:
|
|
|
|
elog(ERROR, "unrecognized item type: %d", item->itemtype);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove tuples from pg_amop and pg_amproc.
|
|
|
|
*/
|
Allow on-the-fly capture of DDL event details
This feature lets user code inspect and take action on DDL events.
Whenever a ddl_command_end event trigger is installed, DDL actions
executed are saved to a list which can be inspected during execution of
a function attached to ddl_command_end.
The set-returning function pg_event_trigger_ddl_commands can be used to
list actions so captured; it returns data about the type of command
executed, as well as the affected object. This is sufficient for many
uses of this feature. For the cases where it is not, we also provide a
"command" column of a new pseudo-type pg_ddl_command, which is a
pointer to a C structure that can be accessed by C code. The struct
contains all the info necessary to completely inspect and even
reconstruct the executed command.
There is no actual deparse code here; that's expected to come later.
What we have is enough infrastructure that the deparsing can be done in
an external extension. The intention is that we will add some deparsing
code in a later release, as an in-core extension.
A new test module is included. It's probably insufficient as is, but it
should be sufficient as a starting point for a more complete and
future-proof approach.
Authors: Álvaro Herrera, with some help from Andres Freund, Ian Barwick,
Abhijit Menon-Sen.
Reviews by Andres Freund, Robert Haas, Amit Kapila, Michael Paquier,
Craig Ringer, David Steele.
Additional input from Chris Browne, Dimitri Fontaine, Stephen Frost,
Petr Jelínek, Tom Lane, Jim Nasby, Steven Singer, Pavel Stěhule.
Based on original work by Dimitri Fontaine, though I didn't use his
code.
Discussion:
https://www.postgresql.org/message-id/m2txrsdzxa.fsf@2ndQuadrant.fr
https://www.postgresql.org/message-id/20131108153322.GU5809@eldon.alvh.no-ip.org
https://www.postgresql.org/message-id/20150215044814.GL3391@alvh.no-ip.org
2015-05-12 00:14:31 +02:00
|
|
|
dropOperators(stmt->opfamilyname, amoid, opfamilyoid, operators);
|
|
|
|
dropProcedures(stmt->opfamilyname, amoid, opfamilyoid, procedures);
|
|
|
|
|
|
|
|
/* make information available to event triggers */
|
|
|
|
EventTriggerCollectAlterOpFam(stmt, opfamilyoid,
|
|
|
|
operators, procedures);
|
2007-01-23 06:07:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Deal with explicit arg types used in ALTER ADD/DROP
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
processTypesSpec(List *args, Oid *lefttype, Oid *righttype)
|
|
|
|
{
|
|
|
|
TypeName *typeName;
|
|
|
|
|
|
|
|
Assert(args != NIL);
|
|
|
|
|
|
|
|
typeName = (TypeName *) linitial(args);
|
2010-10-25 20:40:46 +02:00
|
|
|
*lefttype = typenameTypeId(NULL, typeName);
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
if (list_length(args) > 1)
|
|
|
|
{
|
|
|
|
typeName = (TypeName *) lsecond(args);
|
2010-10-25 20:40:46 +02:00
|
|
|
*righttype = typenameTypeId(NULL, typeName);
|
2007-01-23 06:07:18 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
*righttype = *lefttype;
|
|
|
|
|
|
|
|
if (list_length(args) > 2)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
|
|
errmsg("one or two argument types must be specified")));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the lefttype/righttype to assign to an operator,
|
|
|
|
* and do any validity checking we can manage.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid)
|
|
|
|
{
|
|
|
|
Operator optup;
|
|
|
|
Form_pg_operator opform;
|
|
|
|
|
|
|
|
/* Fetch the operator definition */
|
2010-02-14 19:42:19 +01:00
|
|
|
optup = SearchSysCache1(OPEROID, ObjectIdGetDatum(member->object));
|
2019-05-05 19:10:07 +02:00
|
|
|
if (!HeapTupleIsValid(optup))
|
2007-01-23 06:07:18 +01:00
|
|
|
elog(ERROR, "cache lookup failed for operator %u", member->object);
|
|
|
|
opform = (Form_pg_operator) GETSTRUCT(optup);
|
|
|
|
|
|
|
|
/*
|
2010-11-24 20:20:39 +01:00
|
|
|
* Opfamily operators must be binary.
|
2007-01-23 06:07:18 +01:00
|
|
|
*/
|
|
|
|
if (opform->oprkind != 'b')
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("index operators must be binary")));
|
2010-11-24 20:20:39 +01:00
|
|
|
|
|
|
|
if (OidIsValid(member->sortfamily))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Ordering op, check index supports that. (We could perhaps also
|
|
|
|
* check that the operator returns a type supported by the sortfamily,
|
|
|
|
* but that seems more trouble than it's worth here. If it does not,
|
|
|
|
* the operator will never be matchable to any ORDER BY clause, but no
|
|
|
|
* worse consequences can ensue. Also, trying to check that would
|
|
|
|
* create an ordering hazard during dump/reload: it's possible that
|
|
|
|
* the family has been created but not yet populated with the required
|
|
|
|
* operators.)
|
|
|
|
*/
|
2016-08-14 00:31:14 +02:00
|
|
|
IndexAmRoutine *amroutine = GetIndexAmRoutineByAmId(amoid, false);
|
2010-11-24 20:20:39 +01:00
|
|
|
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
if (!amroutine->amcanorderbyop)
|
2010-11-24 20:20:39 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("access method \"%s\" does not support ordering operators",
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
get_am_name(amoid))));
|
2010-11-24 20:20:39 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Search operators must return boolean.
|
|
|
|
*/
|
|
|
|
if (opform->oprresult != BOOLOID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("index search operators must return boolean")));
|
|
|
|
}
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If lefttype/righttype isn't specified, use the operator's input types
|
|
|
|
*/
|
|
|
|
if (!OidIsValid(member->lefttype))
|
|
|
|
member->lefttype = opform->oprleft;
|
|
|
|
if (!OidIsValid(member->righttype))
|
|
|
|
member->righttype = opform->oprright;
|
|
|
|
|
|
|
|
ReleaseSysCache(optup);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine the lefttype/righttype to assign to a support procedure,
|
|
|
|
* and do any validity checking we can manage.
|
|
|
|
*/
|
|
|
|
static void
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid,
|
|
|
|
int opclassOptsProcNum)
|
2007-01-23 06:07:18 +01:00
|
|
|
{
|
|
|
|
HeapTuple proctup;
|
|
|
|
Form_pg_proc procform;
|
|
|
|
|
|
|
|
/* Fetch the procedure definition */
|
2010-02-14 19:42:19 +01:00
|
|
|
proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(member->object));
|
2019-05-05 19:10:07 +02:00
|
|
|
if (!HeapTupleIsValid(proctup))
|
2007-01-23 06:07:18 +01:00
|
|
|
elog(ERROR, "cache lookup failed for function %u", member->object);
|
|
|
|
procform = (Form_pg_proc) GETSTRUCT(proctup);
|
|
|
|
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
/* Check the signature of the opclass options parsing function */
|
|
|
|
if (member->number == opclassOptsProcNum)
|
|
|
|
{
|
|
|
|
if (OidIsValid(typeoid))
|
|
|
|
{
|
|
|
|
if ((OidIsValid(member->lefttype) && member->lefttype != typeoid) ||
|
|
|
|
(OidIsValid(member->righttype) && member->righttype != typeoid))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2020-09-14 06:42:07 +02:00
|
|
|
errmsg("associated data types for operator class options parsing functions must match opclass input type")));
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (member->lefttype != member->righttype)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2020-09-14 06:42:07 +02:00
|
|
|
errmsg("left and right associated data types for operator class options parsing functions must match")));
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (procform->prorettype != VOIDOID ||
|
|
|
|
procform->pronargs != 1 ||
|
|
|
|
procform->proargtypes.values[0] != INTERNALOID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2020-09-14 06:42:07 +02:00
|
|
|
errmsg("invalid operator class options parsing function"),
|
|
|
|
errhint("Valid signature of operator class options parsing function is %s.",
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
"(internal) RETURNS void")));
|
|
|
|
}
|
2020-03-31 16:51:57 +02:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/*
|
Support all SQL:2011 options for window frame clauses.
This patch adds the ability to use "RANGE offset PRECEDING/FOLLOWING"
frame boundaries in window functions. We'd punted on that back in the
original patch to add window functions, because it was not clear how to
do it in a reasonably data-type-extensible fashion. That problem is
resolved here by adding the ability for btree operator classes to provide
an "in_range" support function that defines how to add or subtract the
RANGE offset value. Factoring it this way also allows the operator class
to avoid overflow problems near the ends of the datatype's range, if it
wishes to expend effort on that. (In the committed patch, the integer
opclasses handle that issue, but it did not seem worth the trouble to
avoid overflow failures for datetime types.)
The patch includes in_range support for the integer_ops opfamily
(int2/int4/int8) as well as the standard datetime types. Support for
other numeric types has been requested, but that seems like suitable
material for a follow-on patch.
In addition, the patch adds GROUPS mode which counts the offset in
ORDER-BY peer groups rather than rows, and it adds the frame_exclusion
options specified by SQL:2011. As far as I can see, we are now fully
up to spec on window framing options.
Existing behaviors remain unchanged, except that I changed the errcode
for a couple of existing error reports to meet the SQL spec's expectation
that negative "offset" values should be reported as SQLSTATE 22013.
Internally and in relevant parts of the documentation, we now consistently
use the terminology "offset PRECEDING/FOLLOWING" rather than "value
PRECEDING/FOLLOWING", since the term "value" is confusingly vague.
Oliver Ford, reviewed and whacked around some by me
Discussion: https://postgr.es/m/CAGMVOdu9sivPAxbNN0X+q19Sfv9edEPv=HibOJhB14TJv_RCQg@mail.gmail.com
2018-02-07 06:06:50 +01:00
|
|
|
* btree comparison procs must be 2-arg procs returning int4. btree
|
|
|
|
* sortsupport procs must take internal and return void. btree in_range
|
2020-02-26 20:28:25 +01:00
|
|
|
* procs must be 5-arg procs returning bool. btree equalimage procs must
|
|
|
|
* take 1 arg and return bool. hash support proc 1 must be a 1-arg proc
|
|
|
|
* returning int4, while proc 2 must be a 2-arg proc returning int8.
|
|
|
|
* Otherwise we don't know.
|
2007-01-23 06:07:18 +01:00
|
|
|
*/
|
Implement operator class parameters
PostgreSQL provides set of template index access methods, where opclasses have
much freedom in the semantics of indexing. These index AMs are GiST, GIN,
SP-GiST and BRIN. There opclasses define representation of keys, operations on
them and supported search strategies. So, it's natural that opclasses may be
faced some tradeoffs, which require user-side decision. This commit implements
opclass parameters allowing users to set some values, which tell opclass how to
index the particular dataset.
This commit doesn't introduce new storage in system catalog. Instead it uses
pg_attribute.attoptions, which is used for table column storage options but
unused for index attributes.
In order to evade changing signature of each opclass support function, we
implement unified way to pass options to opclass support functions. Options
are set to fn_expr as the constant bytea expression. It's possible due to the
fact that opclass support functions are executed outside of expressions, so
fn_expr is unused for them.
This commit comes with some examples of opclass options usage. We parametrize
signature length in GiST. That applies to multiple opclasses: tsvector_ops,
gist__intbig_ops, gist_ltree_ops, gist__ltree_ops, gist_trgm_ops and
gist_hstore_ops. Also we parametrize maximum number of integer ranges for
gist__int_ops. However, the main future usage of this feature is expected
to be json, where users would be able to specify which way to index particular
json parts.
Catversion is bumped.
Discussion: https://postgr.es/m/d22c3a18-31c7-1879-fc11-4c1ce2f5e5af%40postgrespro.ru
Author: Nikita Glukhov, revised by me
Reviwed-by: Nikolay Shaplov, Robert Haas, Tom Lane, Tomas Vondra, Alvaro Herrera
2020-03-30 18:17:11 +02:00
|
|
|
else if (amoid == BTREE_AM_OID)
|
2007-01-23 06:07:18 +01:00
|
|
|
{
|
2011-12-07 06:18:38 +01:00
|
|
|
if (member->number == BTORDER_PROC)
|
|
|
|
{
|
|
|
|
if (procform->pronargs != 2)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("btree comparison functions must have two arguments")));
|
2011-12-07 06:18:38 +01:00
|
|
|
if (procform->prorettype != INT4OID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("btree comparison functions must return integer")));
|
2007-01-23 06:07:18 +01:00
|
|
|
|
2011-12-07 06:18:38 +01:00
|
|
|
/*
|
|
|
|
* If lefttype/righttype isn't specified, use the proc's input
|
|
|
|
* types
|
|
|
|
*/
|
|
|
|
if (!OidIsValid(member->lefttype))
|
|
|
|
member->lefttype = procform->proargtypes.values[0];
|
|
|
|
if (!OidIsValid(member->righttype))
|
|
|
|
member->righttype = procform->proargtypes.values[1];
|
|
|
|
}
|
|
|
|
else if (member->number == BTSORTSUPPORT_PROC)
|
|
|
|
{
|
|
|
|
if (procform->pronargs != 1 ||
|
|
|
|
procform->proargtypes.values[0] != INTERNALOID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("btree sort support functions must accept type \"internal\"")));
|
2011-12-07 06:18:38 +01:00
|
|
|
if (procform->prorettype != VOIDOID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("btree sort support functions must return void")));
|
2011-12-07 06:18:38 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Can't infer lefttype/righttype from proc, so use default rule
|
|
|
|
*/
|
|
|
|
}
|
Support all SQL:2011 options for window frame clauses.
This patch adds the ability to use "RANGE offset PRECEDING/FOLLOWING"
frame boundaries in window functions. We'd punted on that back in the
original patch to add window functions, because it was not clear how to
do it in a reasonably data-type-extensible fashion. That problem is
resolved here by adding the ability for btree operator classes to provide
an "in_range" support function that defines how to add or subtract the
RANGE offset value. Factoring it this way also allows the operator class
to avoid overflow problems near the ends of the datatype's range, if it
wishes to expend effort on that. (In the committed patch, the integer
opclasses handle that issue, but it did not seem worth the trouble to
avoid overflow failures for datetime types.)
The patch includes in_range support for the integer_ops opfamily
(int2/int4/int8) as well as the standard datetime types. Support for
other numeric types has been requested, but that seems like suitable
material for a follow-on patch.
In addition, the patch adds GROUPS mode which counts the offset in
ORDER-BY peer groups rather than rows, and it adds the frame_exclusion
options specified by SQL:2011. As far as I can see, we are now fully
up to spec on window framing options.
Existing behaviors remain unchanged, except that I changed the errcode
for a couple of existing error reports to meet the SQL spec's expectation
that negative "offset" values should be reported as SQLSTATE 22013.
Internally and in relevant parts of the documentation, we now consistently
use the terminology "offset PRECEDING/FOLLOWING" rather than "value
PRECEDING/FOLLOWING", since the term "value" is confusingly vague.
Oliver Ford, reviewed and whacked around some by me
Discussion: https://postgr.es/m/CAGMVOdu9sivPAxbNN0X+q19Sfv9edEPv=HibOJhB14TJv_RCQg@mail.gmail.com
2018-02-07 06:06:50 +01:00
|
|
|
else if (member->number == BTINRANGE_PROC)
|
|
|
|
{
|
|
|
|
if (procform->pronargs != 5)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("btree in_range functions must have five arguments")));
|
Support all SQL:2011 options for window frame clauses.
This patch adds the ability to use "RANGE offset PRECEDING/FOLLOWING"
frame boundaries in window functions. We'd punted on that back in the
original patch to add window functions, because it was not clear how to
do it in a reasonably data-type-extensible fashion. That problem is
resolved here by adding the ability for btree operator classes to provide
an "in_range" support function that defines how to add or subtract the
RANGE offset value. Factoring it this way also allows the operator class
to avoid overflow problems near the ends of the datatype's range, if it
wishes to expend effort on that. (In the committed patch, the integer
opclasses handle that issue, but it did not seem worth the trouble to
avoid overflow failures for datetime types.)
The patch includes in_range support for the integer_ops opfamily
(int2/int4/int8) as well as the standard datetime types. Support for
other numeric types has been requested, but that seems like suitable
material for a follow-on patch.
In addition, the patch adds GROUPS mode which counts the offset in
ORDER-BY peer groups rather than rows, and it adds the frame_exclusion
options specified by SQL:2011. As far as I can see, we are now fully
up to spec on window framing options.
Existing behaviors remain unchanged, except that I changed the errcode
for a couple of existing error reports to meet the SQL spec's expectation
that negative "offset" values should be reported as SQLSTATE 22013.
Internally and in relevant parts of the documentation, we now consistently
use the terminology "offset PRECEDING/FOLLOWING" rather than "value
PRECEDING/FOLLOWING", since the term "value" is confusingly vague.
Oliver Ford, reviewed and whacked around some by me
Discussion: https://postgr.es/m/CAGMVOdu9sivPAxbNN0X+q19Sfv9edEPv=HibOJhB14TJv_RCQg@mail.gmail.com
2018-02-07 06:06:50 +01:00
|
|
|
if (procform->prorettype != BOOLOID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("btree in_range functions must return boolean")));
|
Support all SQL:2011 options for window frame clauses.
This patch adds the ability to use "RANGE offset PRECEDING/FOLLOWING"
frame boundaries in window functions. We'd punted on that back in the
original patch to add window functions, because it was not clear how to
do it in a reasonably data-type-extensible fashion. That problem is
resolved here by adding the ability for btree operator classes to provide
an "in_range" support function that defines how to add or subtract the
RANGE offset value. Factoring it this way also allows the operator class
to avoid overflow problems near the ends of the datatype's range, if it
wishes to expend effort on that. (In the committed patch, the integer
opclasses handle that issue, but it did not seem worth the trouble to
avoid overflow failures for datetime types.)
The patch includes in_range support for the integer_ops opfamily
(int2/int4/int8) as well as the standard datetime types. Support for
other numeric types has been requested, but that seems like suitable
material for a follow-on patch.
In addition, the patch adds GROUPS mode which counts the offset in
ORDER-BY peer groups rather than rows, and it adds the frame_exclusion
options specified by SQL:2011. As far as I can see, we are now fully
up to spec on window framing options.
Existing behaviors remain unchanged, except that I changed the errcode
for a couple of existing error reports to meet the SQL spec's expectation
that negative "offset" values should be reported as SQLSTATE 22013.
Internally and in relevant parts of the documentation, we now consistently
use the terminology "offset PRECEDING/FOLLOWING" rather than "value
PRECEDING/FOLLOWING", since the term "value" is confusingly vague.
Oliver Ford, reviewed and whacked around some by me
Discussion: https://postgr.es/m/CAGMVOdu9sivPAxbNN0X+q19Sfv9edEPv=HibOJhB14TJv_RCQg@mail.gmail.com
2018-02-07 06:06:50 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If lefttype/righttype isn't specified, use the proc's input
|
|
|
|
* types (we look at the test-value and offset arguments)
|
|
|
|
*/
|
|
|
|
if (!OidIsValid(member->lefttype))
|
|
|
|
member->lefttype = procform->proargtypes.values[0];
|
|
|
|
if (!OidIsValid(member->righttype))
|
|
|
|
member->righttype = procform->proargtypes.values[2];
|
|
|
|
}
|
2020-02-26 20:28:25 +01:00
|
|
|
else if (member->number == BTEQUALIMAGE_PROC)
|
|
|
|
{
|
|
|
|
if (procform->pronargs != 1)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("btree equal image functions must have one argument")));
|
|
|
|
if (procform->prorettype != BOOLOID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("btree equal image functions must return boolean")));
|
2020-05-14 19:06:38 +02:00
|
|
|
|
2020-02-26 20:28:25 +01:00
|
|
|
/*
|
|
|
|
* pg_amproc functions are indexed by (lefttype, righttype), but
|
|
|
|
* an equalimage function can only be called at CREATE INDEX time.
|
|
|
|
* The same opclass opcintype OID is always used for leftype and
|
|
|
|
* righttype. Providing a cross-type routine isn't sensible.
|
|
|
|
* Reject cross-type ALTER OPERATOR FAMILY ... ADD FUNCTION 4
|
|
|
|
* statements here.
|
|
|
|
*/
|
|
|
|
if (member->lefttype != member->righttype)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
|
|
|
errmsg("btree equal image functions must not be cross-type")));
|
|
|
|
}
|
2007-01-23 06:07:18 +01:00
|
|
|
}
|
|
|
|
else if (amoid == HASH_AM_OID)
|
|
|
|
{
|
2017-09-01 04:21:21 +02:00
|
|
|
if (member->number == HASHSTANDARD_PROC)
|
|
|
|
{
|
|
|
|
if (procform->pronargs != 1)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("hash function 1 must have one argument")));
|
2017-09-01 04:21:21 +02:00
|
|
|
if (procform->prorettype != INT4OID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("hash function 1 must return integer")));
|
2017-09-01 04:21:21 +02:00
|
|
|
}
|
|
|
|
else if (member->number == HASHEXTENDED_PROC)
|
|
|
|
{
|
|
|
|
if (procform->pronargs != 2)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("hash function 2 must have two arguments")));
|
2017-09-01 04:21:21 +02:00
|
|
|
if (procform->prorettype != INT8OID)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("hash function 2 must return bigint")));
|
2017-09-01 04:21:21 +02:00
|
|
|
}
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If lefttype/righttype isn't specified, use the proc's input type
|
|
|
|
*/
|
|
|
|
if (!OidIsValid(member->lefttype))
|
|
|
|
member->lefttype = procform->proargtypes.values[0];
|
|
|
|
if (!OidIsValid(member->righttype))
|
|
|
|
member->righttype = procform->proargtypes.values[0];
|
|
|
|
}
|
2011-12-07 06:18:38 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The default in CREATE OPERATOR CLASS is to use the class' opcintype as
|
|
|
|
* lefttype and righttype. In CREATE or ALTER OPERATOR FAMILY, opcintype
|
|
|
|
* isn't available, so make the user specify the types.
|
|
|
|
*/
|
|
|
|
if (!OidIsValid(member->lefttype))
|
|
|
|
member->lefttype = typeoid;
|
|
|
|
if (!OidIsValid(member->righttype))
|
|
|
|
member->righttype = typeoid;
|
|
|
|
|
|
|
|
if (!OidIsValid(member->lefttype) || !OidIsValid(member->righttype))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("associated data types must be specified for index support function")));
|
2007-01-23 06:07:18 +01:00
|
|
|
|
|
|
|
ReleaseSysCache(proctup);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Add a new family member to the appropriate list, after checking for
|
|
|
|
* duplicated strategy or proc number.
|
|
|
|
*/
|
|
|
|
static void
|
2020-08-01 23:12:47 +02:00
|
|
|
addFamilyMember(List **list, OpFamilyMember *member)
|
2007-01-23 06:07:18 +01:00
|
|
|
{
|
|
|
|
ListCell *l;
|
|
|
|
|
|
|
|
foreach(l, *list)
|
|
|
|
{
|
|
|
|
OpFamilyMember *old = (OpFamilyMember *) lfirst(l);
|
|
|
|
|
|
|
|
if (old->number == member->number &&
|
|
|
|
old->lefttype == member->lefttype &&
|
|
|
|
old->righttype == member->righttype)
|
|
|
|
{
|
2020-08-01 23:12:47 +02:00
|
|
|
if (member->is_func)
|
2007-01-23 06:07:18 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2018-08-15 17:01:39 +02:00
|
|
|
errmsg("function number %d for (%s,%s) appears more than once",
|
2007-01-23 06:07:18 +01:00
|
|
|
member->number,
|
|
|
|
format_type_be(member->lefttype),
|
2006-12-23 01:43:13 +01:00
|
|
|
format_type_be(member->righttype))));
|
2003-11-12 22:15:59 +01:00
|
|
|
else
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
2006-12-23 01:43:13 +01:00
|
|
|
errmsg("operator number %d for (%s,%s) appears more than once",
|
|
|
|
member->number,
|
|
|
|
format_type_be(member->lefttype),
|
|
|
|
format_type_be(member->righttype))));
|
2003-11-12 22:15:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
*list = lappend(*list, member);
|
|
|
|
}
|
|
|
|
|
2002-07-30 00:14:11 +02:00
|
|
|
/*
|
|
|
|
* Dump the operators to pg_amop
|
2006-12-23 01:43:13 +01:00
|
|
|
*
|
2020-08-01 23:12:47 +02:00
|
|
|
* We also make dependency entries in pg_depend for the pg_amop entries.
|
2002-07-30 00:14:11 +02:00
|
|
|
*/
|
|
|
|
static void
|
2020-08-01 23:12:47 +02:00
|
|
|
storeOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
2007-01-23 06:07:18 +01:00
|
|
|
List *operators, bool isAdd)
|
2002-07-30 00:14:11 +02:00
|
|
|
{
|
|
|
|
Relation rel;
|
|
|
|
Datum values[Natts_pg_amop];
|
2008-11-02 02:45:28 +01:00
|
|
|
bool nulls[Natts_pg_amop];
|
2002-07-30 00:14:11 +02:00
|
|
|
HeapTuple tup;
|
2006-12-23 01:43:13 +01:00
|
|
|
Oid entryoid;
|
|
|
|
ObjectAddress myself,
|
|
|
|
referenced;
|
2004-05-26 06:41:50 +02:00
|
|
|
ListCell *l;
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(AccessMethodOperatorRelationId, RowExclusiveLock);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
foreach(l, operators)
|
2002-07-30 00:14:11 +02:00
|
|
|
{
|
2006-12-23 01:43:13 +01:00
|
|
|
OpFamilyMember *op = (OpFamilyMember *) lfirst(l);
|
2010-11-24 20:20:39 +01:00
|
|
|
char oppurpose;
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/*
|
|
|
|
* If adding to an existing family, check for conflict with an
|
|
|
|
* existing pg_amop entry (just to give a nicer error message)
|
|
|
|
*/
|
|
|
|
if (isAdd &&
|
2010-02-14 19:42:19 +01:00
|
|
|
SearchSysCacheExists4(AMOPSTRATEGY,
|
|
|
|
ObjectIdGetDatum(opfamilyoid),
|
|
|
|
ObjectIdGetDatum(op->lefttype),
|
|
|
|
ObjectIdGetDatum(op->righttype),
|
|
|
|
Int16GetDatum(op->number)))
|
2007-01-23 06:07:18 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("operator %d(%s,%s) already exists in operator family \"%s\"",
|
|
|
|
op->number,
|
|
|
|
format_type_be(op->lefttype),
|
|
|
|
format_type_be(op->righttype),
|
|
|
|
NameListToString(opfamilyname))));
|
|
|
|
|
2010-11-24 20:20:39 +01:00
|
|
|
oppurpose = OidIsValid(op->sortfamily) ? AMOP_ORDER : AMOP_SEARCH;
|
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/* Create the pg_amop entry */
|
|
|
|
memset(values, 0, sizeof(values));
|
2008-11-02 02:45:28 +01:00
|
|
|
memset(nulls, false, sizeof(nulls));
|
2002-07-30 00:14:11 +02: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
|
|
|
entryoid = GetNewOidWithIndex(rel, AccessMethodOperatorOidIndexId,
|
|
|
|
Anum_pg_amop_oid);
|
|
|
|
values[Anum_pg_amop_oid - 1] = ObjectIdGetDatum(entryoid);
|
2006-12-23 01:43:13 +01:00
|
|
|
values[Anum_pg_amop_amopfamily - 1] = ObjectIdGetDatum(opfamilyoid);
|
|
|
|
values[Anum_pg_amop_amoplefttype - 1] = ObjectIdGetDatum(op->lefttype);
|
|
|
|
values[Anum_pg_amop_amoprighttype - 1] = ObjectIdGetDatum(op->righttype);
|
|
|
|
values[Anum_pg_amop_amopstrategy - 1] = Int16GetDatum(op->number);
|
2010-11-24 20:20:39 +01:00
|
|
|
values[Anum_pg_amop_amoppurpose - 1] = CharGetDatum(oppurpose);
|
2006-12-23 01:43:13 +01:00
|
|
|
values[Anum_pg_amop_amopopr - 1] = ObjectIdGetDatum(op->object);
|
|
|
|
values[Anum_pg_amop_amopmethod - 1] = ObjectIdGetDatum(amoid);
|
2010-11-24 20:20:39 +01:00
|
|
|
values[Anum_pg_amop_amopsortfamily - 1] = ObjectIdGetDatum(op->sortfamily);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2008-11-02 02:45:28 +01:00
|
|
|
tup = heap_form_tuple(rel->rd_att, values, nulls);
|
2002-07-30 00:14:11 +02: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
|
|
|
CatalogTupleInsert(rel, tup);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
heap_freetuple(tup);
|
2006-12-23 01:43:13 +01:00
|
|
|
|
|
|
|
/* Make its dependencies */
|
|
|
|
myself.classId = AccessMethodOperatorRelationId;
|
|
|
|
myself.objectId = entryoid;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
|
|
|
referenced.classId = OperatorRelationId;
|
|
|
|
referenced.objectId = op->object;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
|
2020-08-01 23:12:47 +02:00
|
|
|
/* see comments in amapi.h about dependency strength */
|
|
|
|
recordDependencyOn(&myself, &referenced,
|
|
|
|
op->ref_is_hard ? DEPENDENCY_NORMAL : DEPENDENCY_AUTO);
|
2006-12-23 01:43:13 +01:00
|
|
|
|
2020-08-01 23:12:47 +02:00
|
|
|
referenced.classId = op->ref_is_family ? OperatorFamilyRelationId :
|
|
|
|
OperatorClassRelationId;
|
|
|
|
referenced.objectId = op->refobjid;
|
|
|
|
referenced.objectSubId = 0;
|
2006-12-23 01:43:13 +01:00
|
|
|
|
2020-08-01 23:12:47 +02:00
|
|
|
recordDependencyOn(&myself, &referenced,
|
|
|
|
op->ref_is_hard ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO);
|
2010-11-24 20:20:39 +01:00
|
|
|
|
|
|
|
/* A search operator also needs a dep on the referenced opfamily */
|
|
|
|
if (OidIsValid(op->sortfamily))
|
|
|
|
{
|
|
|
|
referenced.classId = OperatorFamilyRelationId;
|
|
|
|
referenced.objectId = op->sortfamily;
|
|
|
|
referenced.objectSubId = 0;
|
2020-08-01 23:12:47 +02:00
|
|
|
|
|
|
|
recordDependencyOn(&myself, &referenced,
|
|
|
|
op->ref_is_hard ? DEPENDENCY_NORMAL : DEPENDENCY_AUTO);
|
2010-11-24 20:20:39 +01:00
|
|
|
}
|
2020-08-01 23:12:47 +02:00
|
|
|
|
2013-03-18 03:55:14 +01:00
|
|
|
/* Post create hook of this access method operator */
|
|
|
|
InvokeObjectPostCreateHook(AccessMethodOperatorRelationId,
|
|
|
|
entryoid, 0);
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dump the procedures (support routines) to pg_amproc
|
2006-12-23 01:43:13 +01:00
|
|
|
*
|
2020-08-01 23:12:47 +02:00
|
|
|
* We also make dependency entries in pg_depend for the pg_amproc entries.
|
2002-07-30 00:14:11 +02:00
|
|
|
*/
|
|
|
|
static void
|
2020-08-01 23:12:47 +02:00
|
|
|
storeProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
2007-01-23 06:07:18 +01:00
|
|
|
List *procedures, bool isAdd)
|
2002-07-30 00:14:11 +02:00
|
|
|
{
|
|
|
|
Relation rel;
|
|
|
|
Datum values[Natts_pg_amproc];
|
2008-11-02 02:45:28 +01:00
|
|
|
bool nulls[Natts_pg_amproc];
|
2002-07-30 00:14:11 +02:00
|
|
|
HeapTuple tup;
|
2006-12-23 01:43:13 +01:00
|
|
|
Oid entryoid;
|
|
|
|
ObjectAddress myself,
|
|
|
|
referenced;
|
2004-05-26 06:41:50 +02:00
|
|
|
ListCell *l;
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
rel = table_open(AccessMethodProcedureRelationId, RowExclusiveLock);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2003-11-12 22:15:59 +01:00
|
|
|
foreach(l, procedures)
|
2002-07-30 00:14:11 +02:00
|
|
|
{
|
2006-12-23 01:43:13 +01:00
|
|
|
OpFamilyMember *proc = (OpFamilyMember *) lfirst(l);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/*
|
|
|
|
* If adding to an existing family, check for conflict with an
|
|
|
|
* existing pg_amproc entry (just to give a nicer error message)
|
|
|
|
*/
|
|
|
|
if (isAdd &&
|
2010-02-14 19:42:19 +01:00
|
|
|
SearchSysCacheExists4(AMPROCNUM,
|
|
|
|
ObjectIdGetDatum(opfamilyoid),
|
|
|
|
ObjectIdGetDatum(proc->lefttype),
|
|
|
|
ObjectIdGetDatum(proc->righttype),
|
|
|
|
Int16GetDatum(proc->number)))
|
2007-01-23 06:07:18 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("function %d(%s,%s) already exists in operator family \"%s\"",
|
|
|
|
proc->number,
|
|
|
|
format_type_be(proc->lefttype),
|
|
|
|
format_type_be(proc->righttype),
|
|
|
|
NameListToString(opfamilyname))));
|
|
|
|
|
2006-12-23 01:43:13 +01:00
|
|
|
/* Create the pg_amproc entry */
|
|
|
|
memset(values, 0, sizeof(values));
|
2008-11-02 02:45:28 +01:00
|
|
|
memset(nulls, false, sizeof(nulls));
|
2002-07-30 00:14:11 +02: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
|
|
|
entryoid = GetNewOidWithIndex(rel, AccessMethodProcedureOidIndexId,
|
|
|
|
Anum_pg_amproc_oid);
|
|
|
|
values[Anum_pg_amproc_oid - 1] = ObjectIdGetDatum(entryoid);
|
2006-12-23 01:43:13 +01:00
|
|
|
values[Anum_pg_amproc_amprocfamily - 1] = ObjectIdGetDatum(opfamilyoid);
|
|
|
|
values[Anum_pg_amproc_amproclefttype - 1] = ObjectIdGetDatum(proc->lefttype);
|
|
|
|
values[Anum_pg_amproc_amprocrighttype - 1] = ObjectIdGetDatum(proc->righttype);
|
|
|
|
values[Anum_pg_amproc_amprocnum - 1] = Int16GetDatum(proc->number);
|
|
|
|
values[Anum_pg_amproc_amproc - 1] = ObjectIdGetDatum(proc->object);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
2008-11-02 02:45:28 +01:00
|
|
|
tup = heap_form_tuple(rel->rd_att, values, nulls);
|
2002-07-30 00:14:11 +02: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
|
|
|
CatalogTupleInsert(rel, tup);
|
2002-07-30 00:14:11 +02:00
|
|
|
|
|
|
|
heap_freetuple(tup);
|
2006-12-23 01:43:13 +01:00
|
|
|
|
|
|
|
/* Make its dependencies */
|
|
|
|
myself.classId = AccessMethodProcedureRelationId;
|
|
|
|
myself.objectId = entryoid;
|
|
|
|
myself.objectSubId = 0;
|
|
|
|
|
|
|
|
referenced.classId = ProcedureRelationId;
|
|
|
|
referenced.objectId = proc->object;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
|
2020-08-01 23:12:47 +02:00
|
|
|
/* see comments in amapi.h about dependency strength */
|
|
|
|
recordDependencyOn(&myself, &referenced,
|
|
|
|
proc->ref_is_hard ? DEPENDENCY_NORMAL : DEPENDENCY_AUTO);
|
2006-12-23 01:43:13 +01:00
|
|
|
|
2020-08-01 23:12:47 +02:00
|
|
|
referenced.classId = proc->ref_is_family ? OperatorFamilyRelationId :
|
|
|
|
OperatorClassRelationId;
|
|
|
|
referenced.objectId = proc->refobjid;
|
|
|
|
referenced.objectSubId = 0;
|
|
|
|
|
|
|
|
recordDependencyOn(&myself, &referenced,
|
|
|
|
proc->ref_is_hard ? DEPENDENCY_INTERNAL : DEPENDENCY_AUTO);
|
2006-12-23 01:43:13 +01:00
|
|
|
|
2013-03-18 03:55:14 +01:00
|
|
|
/* Post create hook of access method procedure */
|
|
|
|
InvokeObjectPostCreateHook(AccessMethodProcedureRelationId,
|
|
|
|
entryoid, 0);
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
|
|
|
|
2019-01-21 19:32:19 +01:00
|
|
|
table_close(rel, RowExclusiveLock);
|
2002-07-30 00:14:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-23 06:07:18 +01:00
|
|
|
/*
|
|
|
|
* Remove operator entries from an opfamily.
|
|
|
|
*
|
|
|
|
* Note: this is only allowed for "loose" members of an opfamily, hence
|
|
|
|
* behavior is always RESTRICT.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
|
|
|
List *operators)
|
|
|
|
{
|
|
|
|
ListCell *l;
|
|
|
|
|
|
|
|
foreach(l, operators)
|
|
|
|
{
|
|
|
|
OpFamilyMember *op = (OpFamilyMember *) lfirst(l);
|
|
|
|
Oid amopid;
|
|
|
|
ObjectAddress object;
|
|
|
|
|
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
|
|
|
amopid = GetSysCacheOid4(AMOPSTRATEGY, Anum_pg_amop_oid,
|
2010-02-14 19:42:19 +01:00
|
|
|
ObjectIdGetDatum(opfamilyoid),
|
|
|
|
ObjectIdGetDatum(op->lefttype),
|
|
|
|
ObjectIdGetDatum(op->righttype),
|
|
|
|
Int16GetDatum(op->number));
|
2007-01-23 06:07:18 +01:00
|
|
|
if (!OidIsValid(amopid))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("operator %d(%s,%s) does not exist in operator family \"%s\"",
|
|
|
|
op->number,
|
|
|
|
format_type_be(op->lefttype),
|
|
|
|
format_type_be(op->righttype),
|
|
|
|
NameListToString(opfamilyname))));
|
|
|
|
|
|
|
|
object.classId = AccessMethodOperatorRelationId;
|
|
|
|
object.objectId = amopid;
|
|
|
|
object.objectSubId = 0;
|
|
|
|
|
2012-01-26 15:24:54 +01:00
|
|
|
performDeletion(&object, DROP_RESTRICT, 0);
|
2007-01-23 06:07:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove procedure entries from an opfamily.
|
|
|
|
*
|
|
|
|
* Note: this is only allowed for "loose" members of an opfamily, hence
|
|
|
|
* behavior is always RESTRICT.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
|
|
|
List *procedures)
|
|
|
|
{
|
|
|
|
ListCell *l;
|
|
|
|
|
|
|
|
foreach(l, procedures)
|
|
|
|
{
|
|
|
|
OpFamilyMember *op = (OpFamilyMember *) lfirst(l);
|
|
|
|
Oid amprocid;
|
|
|
|
ObjectAddress object;
|
|
|
|
|
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
|
|
|
amprocid = GetSysCacheOid4(AMPROCNUM, Anum_pg_amproc_oid,
|
2010-02-14 19:42:19 +01:00
|
|
|
ObjectIdGetDatum(opfamilyoid),
|
|
|
|
ObjectIdGetDatum(op->lefttype),
|
|
|
|
ObjectIdGetDatum(op->righttype),
|
|
|
|
Int16GetDatum(op->number));
|
2007-01-23 06:07:18 +01:00
|
|
|
if (!OidIsValid(amprocid))
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
|
|
|
errmsg("function %d(%s,%s) does not exist in operator family \"%s\"",
|
|
|
|
op->number,
|
|
|
|
format_type_be(op->lefttype),
|
|
|
|
format_type_be(op->righttype),
|
|
|
|
NameListToString(opfamilyname))));
|
|
|
|
|
|
|
|
object.classId = AccessMethodProcedureRelationId;
|
|
|
|
object.objectId = amprocid;
|
|
|
|
object.objectSubId = 0;
|
|
|
|
|
2012-01-26 15:24:54 +01:00
|
|
|
performDeletion(&object, DROP_RESTRICT, 0);
|
2007-01-23 06:07:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-21 16:06:41 +01:00
|
|
|
/*
|
|
|
|
* Subroutine for ALTER OPERATOR CLASS SET SCHEMA/RENAME
|
|
|
|
*
|
|
|
|
* Is there an operator class with the given name and signature already
|
|
|
|
* in the given namespace? If so, raise an appropriate error message.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
IsThereOpClassInNamespace(const char *opcname, Oid opcmethod,
|
|
|
|
Oid opcnamespace)
|
|
|
|
{
|
2003-06-27 16:45:32 +02:00
|
|
|
/* make sure the new name doesn't exist */
|
2010-02-14 19:42:19 +01:00
|
|
|
if (SearchSysCacheExists3(CLAAMNAMENSP,
|
2013-01-21 16:06:41 +01:00
|
|
|
ObjectIdGetDatum(opcmethod),
|
|
|
|
CStringGetDatum(opcname),
|
|
|
|
ObjectIdGetDatum(opcnamespace)))
|
2003-06-27 16:45:32 +02:00
|
|
|
ereport(ERROR,
|
2003-07-19 01:20:33 +02:00
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
2003-06-27 16:45:32 +02:00
|
|
|
errmsg("operator class \"%s\" for access method \"%s\" already exists in schema \"%s\"",
|
2013-01-21 16:06:41 +01:00
|
|
|
opcname,
|
|
|
|
get_am_name(opcmethod),
|
|
|
|
get_namespace_name(opcnamespace))));
|
2003-06-27 16:45:32 +02:00
|
|
|
}
|
2004-06-25 23:55:59 +02:00
|
|
|
|
|
|
|
/*
|
2013-01-21 16:06:41 +01:00
|
|
|
* Subroutine for ALTER OPERATOR FAMILY SET SCHEMA/RENAME
|
|
|
|
*
|
|
|
|
* Is there an operator family with the given name and signature already
|
|
|
|
* in the given namespace? If so, raise an appropriate error message.
|
2005-11-21 13:49:33 +01:00
|
|
|
*/
|
2013-01-21 16:06:41 +01:00
|
|
|
void
|
|
|
|
IsThereOpFamilyInNamespace(const char *opfname, Oid opfmethod,
|
|
|
|
Oid opfnamespace)
|
2005-11-21 13:49:33 +01:00
|
|
|
{
|
2007-01-23 06:07:18 +01:00
|
|
|
/* make sure the new name doesn't exist */
|
2010-02-14 19:42:19 +01:00
|
|
|
if (SearchSysCacheExists3(OPFAMILYAMNAMENSP,
|
2013-01-21 16:06:41 +01:00
|
|
|
ObjectIdGetDatum(opfmethod),
|
|
|
|
CStringGetDatum(opfname),
|
|
|
|
ObjectIdGetDatum(opfnamespace)))
|
2007-01-23 06:07:18 +01:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
|
|
|
errmsg("operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"",
|
2013-01-21 16:06:41 +01:00
|
|
|
opfname,
|
|
|
|
get_am_name(opfmethod),
|
|
|
|
get_namespace_name(opfnamespace))));
|
2005-11-21 13:49:33 +01:00
|
|
|
}
|