Commit a33cf104 authored by Tom Lane's avatar Tom Lane

Add CREATE/ALTER/DROP OPERATOR FAMILY commands, also COMMENT ON OPERATOR

FAMILY; and add FAMILY option to CREATE OPERATOR CLASS to allow adding a
class to a pre-existing family.  Per previous discussion.  Man, what a
tedious lot of cutting and pasting ...
parent 8502b685
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.68 2006/09/18 19:54:01 tgl Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/allfiles.sgml,v 1.69 2007/01/23 05:07:16 tgl Exp $
PostgreSQL documentation
Complete list of usable sgml source files in this directory.
-->
......@@ -16,6 +16,7 @@ Complete list of usable sgml source files in this directory.
<!entity alterLanguage system "alter_language.sgml">
<!entity alterOperator system "alter_operator.sgml">
<!entity alterOperatorClass system "alter_opclass.sgml">
<!entity alterOperatorFamily system "alter_opfamily.sgml">
<!entity alterRole system "alter_role.sgml">
<!entity alterSchema system "alter_schema.sgml">
<!entity alterSequence system "alter_sequence.sgml">
......@@ -45,6 +46,7 @@ Complete list of usable sgml source files in this directory.
<!entity createLanguage system "create_language.sgml">
<!entity createOperator system "create_operator.sgml">
<!entity createOperatorClass system "create_opclass.sgml">
<!entity createOperatorFamily system "create_opfamily.sgml">
<!entity createRole system "create_role.sgml">
<!entity createRule system "create_rule.sgml">
<!entity createSchema system "create_schema.sgml">
......@@ -70,6 +72,7 @@ Complete list of usable sgml source files in this directory.
<!entity dropLanguage system "drop_language.sgml">
<!entity dropOperator system "drop_operator.sgml">
<!entity dropOperatorClass system "drop_opclass.sgml">
<!entity dropOperatorFamily system "drop_opfamily.sgml">
<!entity dropOwned system "drop_owned.sgml">
<!entity dropRole system "drop_role.sgml">
<!entity dropRule system "drop_rule.sgml">
......
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_opclass.sgml,v 1.7 2006/09/16 00:30:16 momjian Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_opclass.sgml,v 1.8 2007/01/23 05:07:17 tgl Exp $
PostgreSQL documentation
-->
......@@ -102,6 +102,7 @@ ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="p
<simplelist type="inline">
<member><xref linkend="sql-createopclass" endterm="sql-createopclass-title"></member>
<member><xref linkend="sql-dropopclass" endterm="sql-dropopclass-title"></member>
<member><xref linkend="sql-alteropfamily" endterm="sql-alteropfamily-title"></member>
</simplelist>
</refsect1>
</refentry>
This diff is collapsed.
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/comment.sgml,v 1.33 2006/10/23 18:10:32 petere Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/comment.sgml,v 1.34 2007/01/23 05:07:17 tgl Exp $
PostgreSQL documentation
-->
......@@ -35,6 +35,7 @@ COMMENT ON
LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> |
OPERATOR <replaceable class="PARAMETER">op</replaceable> (<replaceable class="PARAMETER">leftoperand_type</replaceable>, <replaceable class="PARAMETER">rightoperand_type</replaceable>) |
OPERATOR CLASS <replaceable class="PARAMETER">object_name</replaceable> USING <replaceable class="parameter">index_method</replaceable> |
OPERATOR FAMILY <replaceable class="PARAMETER">object_name</replaceable> USING <replaceable class="parameter">index_method</replaceable> |
[ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">object_name</replaceable> |
ROLE <replaceable class="PARAMETER">object_name</replaceable> |
RULE <replaceable class="PARAMETER">rule_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
......@@ -92,7 +93,7 @@ COMMENT ON
<para>
The name of the object to be commented. Names of tables,
aggregates, domains, functions, indexes, operators, operator classes,
sequences, types, and views may be schema-qualified.
operator families, sequences, types, and views may be schema-qualified.
</para>
</listitem>
</varlistentry>
......@@ -247,6 +248,7 @@ COMMENT ON LARGE OBJECT 346344 IS 'Planning document';
COMMENT ON OPERATOR ^ (text, text) IS 'Performs intersection of two texts';
COMMENT ON OPERATOR - (NONE, text) IS 'This is a prefix operator on text';
COMMENT ON OPERATOR CLASS int4ops USING btree IS '4 byte integer operators for btrees';
COMMENT ON OPERATOR FAMILY integer_ops USING btree IS 'all integer operators for btrees';
COMMENT ON ROLE my_role IS 'Administration group for finance tables';
COMMENT ON RULE my_rule ON my_table IS 'Logs updates of employee records';
COMMENT ON SCHEMA my_schema IS 'Departmental data';
......
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_opclass.sgml,v 1.18 2006/10/16 17:28:03 momjian Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/create_opclass.sgml,v 1.19 2007/01/23 05:07:17 tgl Exp $
PostgreSQL documentation
-->
......@@ -20,9 +20,10 @@ PostgreSQL documentation
<refsynopsisdiv>
<synopsis>
CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAULT ] FOR TYPE <replaceable class="parameter">data_type</replaceable> USING <replaceable class="parameter">index_method</replaceable> AS
CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAULT ] FOR TYPE <replaceable class="parameter">data_type</replaceable>
USING <replaceable class="parameter">index_method</replaceable> [ FAMILY <replaceable class="parameter">family_name</replaceable> ] AS
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> <replaceable class="parameter">operator_name</replaceable> [ ( <replaceable class="parameter">op_type</replaceable>, <replaceable class="parameter">op_type</replaceable> ) ] [ RECHECK ]
| FUNCTION <replaceable class="parameter">support_number</replaceable> <replaceable class="parameter">funcname</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
| FUNCTION <replaceable class="parameter">support_number</replaceable> [ ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">funcname</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
| STORAGE <replaceable class="parameter">storage_type</replaceable>
} [, ... ]
</synopsis>
......@@ -40,7 +41,7 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
be used by
the index method when the operator class is selected for an
index column. All the operators and functions used by an operator
class must be defined before the operator class is created.
class must be defined before the operator class can be created.
</para>
<para>
......@@ -65,6 +66,15 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
responsibility to define a valid operator class.
</para>
<para>
Related operator classes can be grouped into <firstterm>operator
families</>. To add a new operator class to an existing family,
specify the <literal>FAMILY</> option in <command>CREATE OPERATOR
CLASS</command>. Without this option, the new class is placed into
a family named the same as the new class (creating that family if
it doesn't already exist).
</para>
<para>
Refer to <xref linkend="xindex"> for further information.
</para>
......@@ -113,6 +123,17 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">family_name</replaceable></term>
<listitem>
<para>
The name of the existing operator family to add this operator class to.
If not specified, a family named the same as the operator class is
used (creating it, if it doesn't already exist).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">strategy_number</replaceable></term>
<listitem>
......@@ -137,11 +158,24 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
<term><replaceable class="parameter">op_type</replaceable></term>
<listitem>
<para>
The operand data type(s) of an operator, or <literal>NONE</> to
In an <literal>OPERATOR</> clause,
the operand data type(s) of the operator, or <literal>NONE</> to
signify a left-unary or right-unary operator. The operand data
types may be omitted in the normal case where they are the same
as the operator class's data type.
</para>
<para>
In a <literal>FUNCTION</> clause, the operand data type(s) the
function is intended to support, if different from
the input data type(s) of the function (for B-tree and hash indexes)
or the class's data type (for GIN and GiST indexes). These defaults
are always correct, so there is no point in specifying <replaceable
class="parameter">op_type</replaceable> in a <literal>FUNCTION</> clause
in <command>CREATE OPERATOR CLASS</>, but the option is provided
for consistency with the comparable syntax in
<command>ALTER OPERATOR FAMILY</>.
</para>
</listitem>
</varlistentry>
......@@ -192,7 +226,7 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
<para>
The data type actually stored in the index. Normally this is
the same as the column data type, but some index methods
(GIN and GiST for now) allow it to be different. The
(currently GIN and GiST) allow it to be different. The
<literal>STORAGE</> clause must be omitted unless the index
method allows a different type to be used.
</para>
......@@ -268,6 +302,8 @@ CREATE OPERATOR CLASS gist__int_ops
<simplelist type="inline">
<member><xref linkend="sql-alteropclass" endterm="sql-alteropclass-title"></member>
<member><xref linkend="sql-dropopclass" endterm="sql-dropopclass-title"></member>
<member><xref linkend="sql-createopfamily" endterm="sql-createopfamily-title"></member>
<member><xref linkend="sql-alteropfamily" endterm="sql-alteropfamily-title"></member>
</simplelist>
</refsect1>
</refentry>
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_opfamily.sgml,v 1.1 2007/01/23 05:07:17 tgl Exp $
PostgreSQL documentation
-->
<refentry id="SQL-CREATEOPFAMILY">
<refmeta>
<refentrytitle id="sql-createopfamily-title">CREATE OPERATOR FAMILY</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>CREATE OPERATOR FAMILY</refname>
<refpurpose>define a new operator family</refpurpose>
</refnamediv>
<indexterm zone="sql-createopfamily">
<primary>CREATE OPERATOR FAMILY</primary>
</indexterm>
<refsynopsisdiv>
<synopsis>
CREATE OPERATOR FAMILY <replaceable class="parameter">name</replaceable> USING <replaceable class="parameter">index_method</replaceable>
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>CREATE OPERATOR FAMILY</command> creates a new operator family.
An operator family defines a collection of related operator classes,
and perhaps some additional operators and support functions that are
compatible with these operator classes but not essential for the
functioning of any individual index. (Operators and functions that
are essential to indexes should be grouped within the relevant operator
class, rather than being <quote>loose</> in the operator family.
Typically, single-data-type operators are bound to operator classes,
while cross-data-type operators can be loose in an operator family
containing operator classes for both data types.)
</para>
<para>
The new operator family is initially empty. It should be populated
by issuing subsequent <command>CREATE OPERATOR CLASS</command> commands
to add contained operator classes, and optionally
<command>ALTER OPERATOR FAMILY</command> commands to add <quote>loose</>
operators and their corresponding support functions.
</para>
<para>
If a schema name is given then the operator family is created in the
specified schema. Otherwise it is created in the current schema.
Two operator families in the same schema can have the same name only if they
are for different index methods.
</para>
<para>
The user who defines an operator family becomes its owner. Presently,
the creating user must be a superuser. (This restriction is made because
an erroneous operator family definition could confuse or even crash the
server.)
</para>
<para>
<command>CREATE OPERATOR FAMILY</command> does not presently check
whether the operator family definition includes all the operators and
functions required by the index method, nor whether the operators and
functions form a self-consistent set. It is the user's
responsibility to define a valid operator family.
</para>
<para>
Refer to <xref linkend="xindex"> for further information.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name of the operator family to be created. The name may be
schema-qualified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">index_method</replaceable></term>
<listitem>
<para>
The name of the index method this operator family is for.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
<command>CREATE OPERATOR FAMILY</command> is a
<productname>PostgreSQL</productname> extension. There is no
<command>CREATE OPERATOR FAMILY</command> statement in the SQL
standard.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-alteropfamily" endterm="sql-alteropfamily-title"></member>
<member><xref linkend="sql-dropopfamily" endterm="sql-dropopfamily-title"></member>
<member><xref linkend="sql-createopclass" endterm="sql-createopclass-title"></member>
<member><xref linkend="sql-alteropclass" endterm="sql-alteropclass-title"></member>
<member><xref linkend="sql-dropopclass" endterm="sql-dropopclass-title"></member>
</simplelist>
</refsect1>
</refentry>
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/drop_opclass.sgml,v 1.10 2006/09/16 00:30:18 momjian Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/drop_opclass.sgml,v 1.11 2007/01/23 05:07:17 tgl Exp $
PostgreSQL documentation
-->
......@@ -31,6 +31,13 @@ DROP OPERATOR CLASS [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
<command>DROP OPERATOR CLASS</command> drops an existing operator class.
To execute this command you must be the owner of the operator class.
</para>
<para>
<command>DROP OPERATOR CLASS</command> does not drop any of the operators
or functions referenced by the class. If there are any indexes depending
on the operator class, you will need to specify
<literal>CASCADE</> for the drop to complete.
</para>
</refsect1>
<refsect1>
......@@ -87,6 +94,20 @@ DROP OPERATOR CLASS [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
</variablelist>
</refsect1>
<refsect1>
<title>Notes</title>
<para>
<command>DROP OPERATOR CLASS</> will not drop the operator family
containing the class, even if there is nothing else left in the
family (in particular, in the case where the family was implicitly
created by <command>CREATE OPERATOR CLASS</>). An empty operator
family is harmless, but for the sake of tidiness you may wish to
remove the family with <command>DROP OPERATOR FAMILY</>; or perhaps
better, use <command>DROP OPERATOR FAMILY</> in the first place.
</para>
</refsect1>
<refsect1>
<title>Examples</title>
......@@ -118,6 +139,7 @@ DROP OPERATOR CLASS widget_ops USING btree;
<simplelist type="inline">
<member><xref linkend="sql-alteropclass" endterm="sql-alteropclass-title"></member>
<member><xref linkend="sql-createopclass" endterm="sql-createopclass-title"></member>
<member><xref linkend="sql-dropopfamily" endterm="sql-dropopfamily-title"></member>
</simplelist>
</refsect1>
......
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/drop_opfamily.sgml,v 1.1 2007/01/23 05:07:17 tgl Exp $
PostgreSQL documentation
-->
<refentry id="SQL-DROPOPFAMILY">
<refmeta>
<refentrytitle id="SQL-DROPOPFAMILY-TITLE">DROP OPERATOR FAMILY</refentrytitle>
<refmiscinfo>SQL - Language Statements</refmiscinfo>
</refmeta>
<refnamediv>
<refname>DROP OPERATOR FAMILY</refname>
<refpurpose>remove an operator family</refpurpose>
</refnamediv>
<indexterm zone="sql-dropopfamily">
<primary>DROP OPERATOR FAMILY</primary>
</indexterm>
<refsynopsisdiv>
<synopsis>
DROP OPERATOR FAMILY [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> USING <replaceable class="PARAMETER">index_method</replaceable> [ CASCADE | RESTRICT ]
</synopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para>
<command>DROP OPERATOR FAMILY</command> drops an existing operator family.
To execute this command you must be the owner of the operator family.
</para>
<para>
<command>DROP OPERATOR FAMILY</command> includes dropping any operator
classes contained in the family, but it does not drop any of the operators
or functions referenced by the family. If there are any indexes depending
on operator classes within the family, you will need to specify
<literal>CASCADE</> for the drop to complete.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><literal>IF EXISTS</literal></term>
<listitem>
<para>
Do not throw an error if the operator family does not exist.
A notice is issued in this case.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">name</replaceable></term>
<listitem>
<para>
The name (optionally schema-qualified) of an existing operator family.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><replaceable class="parameter">index_method</replaceable></term>
<listitem>
<para>
The name of the index access method the operator family is for.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CASCADE</literal></term>
<listitem>
<para>
Automatically drop objects that depend on the operator family.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>RESTRICT</literal></term>
<listitem>
<para>
Refuse to drop the operator family if any objects depend on it.
This is the default.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Examples</title>
<para>
Remove the B-tree operator family <literal>float_ops</literal>:
<programlisting>
DROP OPERATOR FAMILY float_ops USING btree;
</programlisting>
This command will not succeed if there are any existing indexes
that use operator classes within the family. Add <literal>CASCADE</> to
drop such indexes along with the operator family.
</para>
</refsect1>
<refsect1>
<title>Compatibility</title>
<para>
There is no <command>DROP OPERATOR FAMILY</command> statement in the
SQL standard.
</para>
</refsect1>
<refsect1>
<title>See Also</title>
<simplelist type="inline">
<member><xref linkend="sql-alteropfamily" endterm="sql-alteropfamily-title"></member>
<member><xref linkend="sql-createopfamily" endterm="sql-createopfamily-title"></member>
<member><xref linkend="sql-alteropclass" endterm="sql-alteropclass-title"></member>
<member><xref linkend="sql-createopclass" endterm="sql-createopclass-title"></member>
<member><xref linkend="sql-dropopclass" endterm="sql-dropopclass-title"></member>
</simplelist>
</refsect1>
</refentry>
<!-- $PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.60 2006/09/18 19:54:01 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/reference.sgml,v 1.61 2007/01/23 05:07:17 tgl Exp $ -->
<part id="reference">
<title>Reference</title>
......@@ -44,6 +44,7 @@
&alterLanguage;
&alterOperator;
&alterOperatorClass;
&alterOperatorFamily;
&alterRole;
&alterSchema;
&alterSequence;
......@@ -73,6 +74,7 @@
&createLanguage;
&createOperator;
&createOperatorClass;
&createOperatorFamily;
&createRole;
&createRule;
&createSchema;
......@@ -98,6 +100,7 @@
&dropLanguage;
&dropOperator;
&dropOperatorClass;
&dropOperatorFamily;
&dropOwned;
&dropRole;
&dropRule;
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.134 2007/01/05 22:19:24 momjian Exp $
* $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.135 2007/01/23 05:07:17 tgl Exp $
*
* NOTES
* See acl.h.
......@@ -30,6 +30,7 @@
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_tablespace.h"
#include "catalog/pg_type.h"
......@@ -1413,6 +1414,8 @@ static const char *const no_priv_msg[MAX_ACL_KIND] =
gettext_noop("permission denied for schema %s"),
/* ACL_KIND_OPCLASS */
gettext_noop("permission denied for operator class %s"),
/* ACL_KIND_OPFAMILY */
gettext_noop("permission denied for operator family %s"),
/* ACL_KIND_CONVERSION */
gettext_noop("permission denied for conversion %s"),
/* ACL_KIND_TABLESPACE */
......@@ -1439,6 +1442,8 @@ static const char *const not_owner_msg[MAX_ACL_KIND] =
gettext_noop("must be owner of schema %s"),
/* ACL_KIND_OPCLASS */
gettext_noop("must be owner of operator class %s"),
/* ACL_KIND_OPFAMILY */
gettext_noop("must be owner of operator family %s"),
/* ACL_KIND_CONVERSION */
gettext_noop("must be owner of conversion %s"),
/* ACL_KIND_TABLESPACE */
......@@ -2239,6 +2244,35 @@ pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
return has_privs_of_role(roleid, ownerId);
}
/*
* Ownership check for an operator family (specified by OID).
*/
bool
pg_opfamily_ownercheck(Oid opf_oid, Oid roleid)
{
HeapTuple tuple;
Oid ownerId;
/* Superusers bypass all permission checking. */
if (superuser_arg(roleid))
return true;
tuple = SearchSysCache(OPFAMILYOID,
ObjectIdGetDatum(opf_oid),
0, 0, 0);
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("operator family with OID %u does not exist",
opf_oid)));
ownerId = ((Form_pg_opfamily) GETSTRUCT(tuple))->opfowner;
ReleaseSysCache(tuple);
return has_privs_of_role(roleid, ownerId);
}
/*
* Ownership check for a database (specified by OID).
*/
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.21 2007/01/05 22:19:25 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/alter.c,v 1.22 2007/01/23 05:07:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -66,6 +66,10 @@ ExecRenameStmt(RenameStmt *stmt)
RenameOpClass(stmt->object, stmt->subname, stmt->newname);
break;
case OBJECT_OPFAMILY:
RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
break;
case OBJECT_ROLE:
RenameRole(stmt->subname, stmt->newname);
break;
......@@ -211,6 +215,10 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
AlterOpClassOwner(stmt->object, stmt->addname, newowner);
break;
case OBJECT_OPFAMILY:
AlterOpFamilyOwner(stmt->object, stmt->addname, newowner);
break;
case OBJECT_SCHEMA:
AlterSchemaOwner((char *) linitial(stmt->object), newowner);
break;
......
......@@ -7,7 +7,7 @@
* Copyright (c) 1996-2007, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.94 2007/01/05 22:19:25 momjian Exp $
* $PostgreSQL: pgsql/src/backend/commands/comment.c,v 1.95 2007/01/23 05:07:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -28,6 +28,7 @@
#include "catalog/pg_namespace.h"
#include "catalog/pg_opclass.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_rewrite.h"
#include "catalog/pg_shdescription.h"
......@@ -72,6 +73,7 @@ static void CommentConstraint(List *qualname, char *comment);
static void CommentConversion(List *qualname, char *comment);
static void CommentLanguage(List *qualname, char *comment);
static void CommentOpClass(List *qualname, List *arguments, char *comment);
static void CommentOpFamily(List *qualname, List *arguments, char *comment);
static void CommentLargeObject(List *qualname, char *comment);
static void CommentCast(List *qualname, List *arguments, char *comment);
static void CommentTablespace(List *qualname, char *comment);
......@@ -134,6 +136,9 @@ CommentObject(CommentStmt *stmt)
case OBJECT_OPCLASS:
CommentOpClass(stmt->objname, stmt->objargs, stmt->comment);
break;
case OBJECT_OPFAMILY:
CommentOpFamily(stmt->objname, stmt->objargs, stmt->comment);
break;
case OBJECT_LARGEOBJECT:
CommentLargeObject(stmt->objname, stmt->comment);
break;
......@@ -1263,6 +1268,92 @@ CommentOpClass(List *qualname, List *arguments, char *comment)
CreateComments(opcID, OperatorClassRelationId, 0, comment);
}
/*
* CommentOpFamily --
*
* This routine is used to allow a user to provide comments on an
* operator family. The operator family for commenting is determined by both
* its name and its argument list which defines the index method
* the operator family is used for. The argument list is expected to contain
* a single name (represented as a string Value node).
*/
static void
CommentOpFamily(List *qualname, List *arguments, char *comment)
{
char *amname;
char *schemaname;
char *opfname;
Oid amID;
Oid opfID;
HeapTuple tuple;
Assert(list_length(arguments) == 1);
amname = strVal(linitial(arguments));
/*
* Get the access method's OID.
*/
amID = GetSysCacheOid(AMNAME,
CStringGetDatum(amname),
0, 0, 0);
if (!OidIsValid(amID))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("access method \"%s\" does not exist",
amname)));
/*
* Look up the opfamily.
*/
/* deconstruct the name list */
DeconstructQualifiedName(qualname, &schemaname, &opfname);
if (schemaname)
{
/* Look in specific schema only */
Oid namespaceId;
namespaceId = LookupExplicitNamespace(schemaname);
tuple = SearchSysCache(OPFAMILYAMNAMENSP,
ObjectIdGetDatum(amID),
PointerGetDatum(opfname),
ObjectIdGetDatum(namespaceId),
0);
}
else
{
/* Unqualified opfamily name, so search the search path */
opfID = OpfamilynameGetOpfid(amID, opfname);
if (!OidIsValid(opfID))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
opfname, amname)));
tuple = SearchSysCache(OPFAMILYOID,
ObjectIdGetDatum(opfID),
0, 0, 0);
}
if (!HeapTupleIsValid(tuple))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
NameListToString(qualname), amname)));
opfID = HeapTupleGetOid(tuple);
/* Permission check: must own opfamily */
if (!pg_opfamily_ownercheck(opfID, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
NameListToString(qualname));
ReleaseSysCache(tuple);
/* Call CreateComments() to create/drop the comments */
CreateComments(opfID, OperatorFamilyRelationId, 0, comment);
}
/*
* CommentLargeObject --
*
......
This diff is collapsed.
......@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.363 2007/01/22 20:00:39 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.364 2007/01/23 05:07:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -2158,6 +2158,19 @@ _copyRemoveOpClassStmt(RemoveOpClassStmt *from)
return newnode;
}
static RemoveOpFamilyStmt *
_copyRemoveOpFamilyStmt(RemoveOpFamilyStmt *from)
{
RemoveOpFamilyStmt *newnode = makeNode(RemoveOpFamilyStmt);
COPY_NODE_FIELD(opfamilyname);
COPY_STRING_FIELD(amname);
COPY_SCALAR_FIELD(behavior);
COPY_SCALAR_FIELD(missing_ok);
return newnode;
}
static RenameStmt *
_copyRenameStmt(RenameStmt *from)
{
......@@ -2332,11 +2345,36 @@ _copyCreateOpClassItem(CreateOpClassItem *from)
COPY_NODE_FIELD(args);
COPY_SCALAR_FIELD(number);
COPY_SCALAR_FIELD(recheck);
COPY_NODE_FIELD(class_args);
COPY_NODE_FIELD(storedtype);
return newnode;
}
static CreateOpFamilyStmt *
_copyCreateOpFamilyStmt(CreateOpFamilyStmt *from)
{
CreateOpFamilyStmt *newnode = makeNode(CreateOpFamilyStmt);
COPY_NODE_FIELD(opfamilyname);
COPY_STRING_FIELD(amname);
return newnode;
}
static AlterOpFamilyStmt *
_copyAlterOpFamilyStmt(AlterOpFamilyStmt *from)
{
AlterOpFamilyStmt *newnode = makeNode(AlterOpFamilyStmt);
COPY_NODE_FIELD(opfamilyname);
COPY_STRING_FIELD(amname);
COPY_SCALAR_FIELD(isDrop);
COPY_NODE_FIELD(items);
return newnode;
}
static CreatedbStmt *
_copyCreatedbStmt(CreatedbStmt *from)
{
......@@ -3163,6 +3201,9 @@ copyObject(void *from)
case T_RemoveOpClassStmt:
retval = _copyRemoveOpClassStmt(from);
break;
case T_RemoveOpFamilyStmt:
retval = _copyRemoveOpFamilyStmt(from);
break;
case T_RenameStmt:
retval = _copyRenameStmt(from);
break;
......@@ -3205,6 +3246,12 @@ copyObject(void *from)
case T_CreateOpClassItem:
retval = _copyCreateOpClassItem(from);
break;
case T_CreateOpFamilyStmt:
retval = _copyCreateOpFamilyStmt(from);
break;
case T_AlterOpFamilyStmt:
retval = _copyAlterOpFamilyStmt(from);
break;
case T_CreatedbStmt:
retval = _copyCreatedbStmt(from);
break;
......
......@@ -18,7 +18,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.296 2007/01/20 20:45:38 tgl Exp $
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.297 2007/01/23 05:07:17 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1053,6 +1053,17 @@ _equalRemoveOpClassStmt(RemoveOpClassStmt *a, RemoveOpClassStmt *b)
return true;
}
static bool
_equalRemoveOpFamilyStmt(RemoveOpFamilyStmt *a, RemoveOpFamilyStmt *b)
{
COMPARE_NODE_FIELD(opfamilyname);
COMPARE_STRING_FIELD(amname);
COMPARE_SCALAR_FIELD(behavior);
COMPARE_SCALAR_FIELD(missing_ok);
return true;
}
static bool
_equalRenameStmt(RenameStmt *a, RenameStmt *b)
{
......@@ -1199,11 +1210,32 @@ _equalCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b)
COMPARE_NODE_FIELD(args);
COMPARE_SCALAR_FIELD(number);
COMPARE_SCALAR_FIELD(recheck);
COMPARE_NODE_FIELD(class_args);
COMPARE_NODE_FIELD(storedtype);
return true;
}
static bool
_equalCreateOpFamilyStmt(CreateOpFamilyStmt *a, CreateOpFamilyStmt *b)
{
COMPARE_NODE_FIELD(opfamilyname);
COMPARE_STRING_FIELD(amname);
return true;
}
static bool
_equalAlterOpFamilyStmt(AlterOpFamilyStmt *a, AlterOpFamilyStmt *b)
{
COMPARE_NODE_FIELD(opfamilyname);
COMPARE_STRING_FIELD(amname);
COMPARE_SCALAR_FIELD(isDrop);
COMPARE_NODE_FIELD(items);
return true;
}
static bool
_equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
{
......@@ -2148,6 +2180,9 @@ equal(void *a, void *b)
case T_RemoveOpClassStmt:
retval = _equalRemoveOpClassStmt(a, b);
break;
case T_RemoveOpFamilyStmt:
retval = _equalRemoveOpFamilyStmt(a, b);
break;
case T_RenameStmt:
retval = _equalRenameStmt(a, b);
break;
......@@ -2190,6 +2225,12 @@ equal(void *a, void *b)
case T_CreateOpClassItem:
retval = _equalCreateOpClassItem(a, b);
break;
case T_CreateOpFamilyStmt:
retval = _equalCreateOpFamilyStmt(a, b);
break;
case T_AlterOpFamilyStmt:
retval = _equalAlterOpFamilyStmt(a, b);
break;
case T_CreatedbStmt:
retval = _equalCreatedbStmt(a, b);
break;
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.182 2007/01/22 01:35:21 tgl Exp $
* $PostgreSQL: pgsql/src/backend/parser/keywords.c,v 1.183 2007/01/23 05:07:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -145,6 +145,7 @@ static const ScanKeyword ScanKeywords[] = {
{"external", EXTERNAL},
{"extract", EXTRACT},
{"false", FALSE_P},
{"family", FAMILY},
{"fetch", FETCH},
{"first", FIRST_P},
{"float", FLOAT_P},
......
......@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.270 2007/01/05 22:19:39 momjian Exp $
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.271 2007/01/23 05:07:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -322,6 +322,8 @@ check_xact_readonly(Node *parsetree)
case T_IndexStmt:
case T_CreatePLangStmt:
case T_CreateOpClassStmt:
case T_CreateOpFamilyStmt:
case T_AlterOpFamilyStmt:
case T_RuleStmt:
case T_CreateSchemaStmt:
case T_CreateSeqStmt:
......@@ -338,6 +340,7 @@ check_xact_readonly(Node *parsetree)
case T_DropRoleStmt:
case T_DropPLangStmt:
case T_RemoveOpClassStmt:
case T_RemoveOpFamilyStmt:
case T_DropPropertyStmt:
case T_GrantStmt:
case T_GrantRoleStmt:
......@@ -1099,10 +1102,22 @@ ProcessUtility(Node *parsetree,
DefineOpClass((CreateOpClassStmt *) parsetree);
break;
case T_CreateOpFamilyStmt:
DefineOpFamily((CreateOpFamilyStmt *) parsetree);
break;
case T_AlterOpFamilyStmt:
AlterOpFamily((AlterOpFamilyStmt *) parsetree);
break;
case T_RemoveOpClassStmt:
RemoveOpClass((RemoveOpClassStmt *) parsetree);
break;
case T_RemoveOpFamilyStmt:
RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(parsetree));
......@@ -1445,6 +1460,9 @@ CreateCommandTag(Node *parsetree)
case OBJECT_OPCLASS:
tag = "ALTER OPERATOR CLASS";
break;
case OBJECT_OPFAMILY:
tag = "ALTER OPERATOR FAMILY";
break;
case OBJECT_ROLE:
tag = "ALTER ROLE";
break;
......@@ -1518,6 +1536,9 @@ CreateCommandTag(Node *parsetree)
case OBJECT_OPCLASS:
tag = "ALTER OPERATOR CLASS";
break;
case OBJECT_OPFAMILY:
tag = "ALTER OPERATOR FAMILY";
break;
case OBJECT_SCHEMA:
tag = "ALTER SCHEMA";
break;
......@@ -1777,10 +1798,22 @@ CreateCommandTag(Node *parsetree)
tag = "CREATE OPERATOR CLASS";
break;
case T_CreateOpFamilyStmt:
tag = "CREATE OPERATOR FAMILY";
break;
case T_AlterOpFamilyStmt:
tag = "ALTER OPERATOR FAMILY";
break;
case T_RemoveOpClassStmt:
tag = "DROP OPERATOR CLASS";
break;
case T_RemoveOpFamilyStmt:
tag = "DROP OPERATOR FAMILY";
break;
case T_PrepareStmt:
tag = "PREPARE";
break;
......@@ -2147,10 +2180,22 @@ GetCommandLogLevel(Node *parsetree)
lev = LOGSTMT_DDL;
break;
case T_CreateOpFamilyStmt:
lev = LOGSTMT_DDL;
break;
case T_AlterOpFamilyStmt:
lev = LOGSTMT_DDL;
break;
case T_RemoveOpClassStmt:
lev = LOGSTMT_DDL;
break;
case T_RemoveOpFamilyStmt:
lev = LOGSTMT_DDL;
break;
case T_PrepareStmt:
{
PrepareStmt *stmt = (PrepareStmt *) parsetree;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.79 2007/01/05 22:19:53 momjian Exp $
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.80 2007/01/23 05:07:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -79,13 +79,18 @@ extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId);
/* commands/opclasscmds.c */
extern void DefineOpClass(CreateOpClassStmt *stmt);
extern void DefineOpFamily(CreateOpFamilyStmt *stmt);
extern void AlterOpFamily(AlterOpFamilyStmt *stmt);
extern void RemoveOpClass(RemoveOpClassStmt *stmt);
extern void RemoveOpFamily(RemoveOpFamilyStmt *stmt);
extern void RemoveOpClassById(Oid opclassOid);
extern void RemoveOpFamilyById(Oid opfamilyOid);
extern void RemoveAmOpEntryById(Oid entryOid);
extern void RemoveAmProcEntryById(Oid entryOid);
extern void RenameOpClass(List *name, const char *access_method, const char *newname);
extern void RenameOpFamily(List *name, const char *access_method, const char *newname);
extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId);
extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
/* support routines in commands/define.c */
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.192 2007/01/20 20:45:40 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.193 2007/01/23 05:07:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -286,7 +286,10 @@ typedef enum NodeTag
T_CreateCastStmt,
T_DropCastStmt,
T_CreateOpClassStmt,
T_CreateOpFamilyStmt,
T_AlterOpFamilyStmt,
T_RemoveOpClassStmt,
T_RemoveOpFamilyStmt,
T_PrepareStmt,
T_ExecuteStmt,
T_DeallocateStmt,
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.338 2007/01/09 02:14:15 tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.339 2007/01/23 05:07:18 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -852,6 +852,7 @@ typedef enum ObjectType
OBJECT_LARGEOBJECT,
OBJECT_OPCLASS,
OBJECT_OPERATOR,
OBJECT_OPFAMILY,
OBJECT_ROLE,
OBJECT_RULE,
OBJECT_SCHEMA,
......@@ -1194,7 +1195,7 @@ typedef struct DropTableSpaceStmt
{
NodeTag type;
char *tablespacename;
bool missing_ok; /* skip error if a missing? */
bool missing_ok; /* skip error if missing? */
} DropTableSpaceStmt;
/* ----------------------
......@@ -1362,10 +1363,35 @@ typedef struct CreateOpClassItem
List *args; /* argument types */
int number; /* strategy num or support proc num */
bool recheck; /* only used for operators */
List *class_args; /* only used for functions */
/* fields used for a storagetype item: */
TypeName *storedtype; /* datatype stored in index */
} CreateOpClassItem;
/* ----------------------
* Create Operator Family Statement
* ----------------------
*/
typedef struct CreateOpFamilyStmt
{
NodeTag type;
List *opfamilyname; /* qualified name (list of Value strings) */
char *amname; /* name of index AM opfamily is for */
} CreateOpFamilyStmt;
/* ----------------------
* Alter Operator Family Statement
* ----------------------
*/
typedef struct AlterOpFamilyStmt
{
NodeTag type;
List *opfamilyname; /* qualified name (list of Value strings) */
char *amname; /* name of index AM opfamily is for */
bool isDrop; /* ADD or DROP the items? */
List *items; /* List of CreateOpClassItem nodes */
} AlterOpFamilyStmt;
/* ----------------------
* Drop Table|Sequence|View|Index|Type|Domain|Conversion|Schema Statement
* ----------------------
......@@ -1395,7 +1421,7 @@ typedef struct DropPropertyStmt
char *property; /* name of rule, trigger, etc */
ObjectType removeType; /* OBJECT_RULE or OBJECT_TRIGGER */
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
bool missing_ok; /* skip error if a missing? */
bool missing_ok; /* skip error if missing? */
} DropPropertyStmt;
/* ----------------------
......@@ -1546,7 +1572,7 @@ typedef struct RemoveFuncStmt
List *name; /* qualified name of object to drop */
List *args; /* types of the arguments */
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
bool missing_ok; /* skip error if a missing? */
bool missing_ok; /* skip error if missing? */
} RemoveFuncStmt;
/* ----------------------
......@@ -1559,9 +1585,22 @@ typedef struct RemoveOpClassStmt
List *opclassname; /* qualified name (list of Value strings) */
char *amname; /* name of index AM opclass is for */
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
bool missing_ok; /* skip error if a missing? */
bool missing_ok; /* skip error if missing? */
} RemoveOpClassStmt;
/* ----------------------
* Drop Operator Family Statement
* ----------------------
*/
typedef struct RemoveOpFamilyStmt
{
NodeTag type;
List *opfamilyname; /* qualified name (list of Value strings) */
char *amname; /* name of index AM opfamily is for */
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
bool missing_ok; /* skip error if missing? */
} RemoveOpFamilyStmt;
/* ----------------------
* Alter Object Rename Statement
* ----------------------
......@@ -1917,7 +1956,7 @@ typedef struct DropCastStmt
TypeName *sourcetype;
TypeName *targettype;
DropBehavior behavior;
bool missing_ok; /* skip error if a missing? */
bool missing_ok; /* skip error if missing? */
} DropCastStmt;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.99 2007/01/05 22:19:58 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.100 2007/01/23 05:07:18 tgl Exp $
*
* NOTES
* An ACL array is simply an array of AclItems, representing the union
......@@ -178,6 +178,7 @@ typedef enum AclObjectKind
ACL_KIND_LANGUAGE, /* pg_language */
ACL_KIND_NAMESPACE, /* pg_namespace */
ACL_KIND_OPCLASS, /* pg_opclass */
ACL_KIND_OPFAMILY, /* pg_opfamily */
ACL_KIND_CONVERSION, /* pg_conversion */
ACL_KIND_TABLESPACE, /* pg_tablespace */
MAX_ACL_KIND /* MUST BE LAST */
......@@ -276,6 +277,7 @@ extern bool pg_proc_ownercheck(Oid proc_oid, Oid roleid);
extern bool pg_namespace_ownercheck(Oid nsp_oid, Oid roleid);
extern bool pg_tablespace_ownercheck(Oid spc_oid, Oid roleid);
extern bool pg_opclass_ownercheck(Oid opc_oid, Oid roleid);
extern bool pg_opfamily_ownercheck(Oid opf_oid, Oid roleid);
extern bool pg_database_ownercheck(Oid db_oid, Oid roleid);
extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment