mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
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 ...
This commit is contained in:
parent
8502b68513
commit
a33cf1041f
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
PostgreSQL documentation
|
||||||
Complete list of usable sgml source files in this directory.
|
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 alterLanguage system "alter_language.sgml">
|
||||||
<!entity alterOperator system "alter_operator.sgml">
|
<!entity alterOperator system "alter_operator.sgml">
|
||||||
<!entity alterOperatorClass system "alter_opclass.sgml">
|
<!entity alterOperatorClass system "alter_opclass.sgml">
|
||||||
|
<!entity alterOperatorFamily system "alter_opfamily.sgml">
|
||||||
<!entity alterRole system "alter_role.sgml">
|
<!entity alterRole system "alter_role.sgml">
|
||||||
<!entity alterSchema system "alter_schema.sgml">
|
<!entity alterSchema system "alter_schema.sgml">
|
||||||
<!entity alterSequence system "alter_sequence.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 createLanguage system "create_language.sgml">
|
||||||
<!entity createOperator system "create_operator.sgml">
|
<!entity createOperator system "create_operator.sgml">
|
||||||
<!entity createOperatorClass system "create_opclass.sgml">
|
<!entity createOperatorClass system "create_opclass.sgml">
|
||||||
|
<!entity createOperatorFamily system "create_opfamily.sgml">
|
||||||
<!entity createRole system "create_role.sgml">
|
<!entity createRole system "create_role.sgml">
|
||||||
<!entity createRule system "create_rule.sgml">
|
<!entity createRule system "create_rule.sgml">
|
||||||
<!entity createSchema system "create_schema.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 dropLanguage system "drop_language.sgml">
|
||||||
<!entity dropOperator system "drop_operator.sgml">
|
<!entity dropOperator system "drop_operator.sgml">
|
||||||
<!entity dropOperatorClass system "drop_opclass.sgml">
|
<!entity dropOperatorClass system "drop_opclass.sgml">
|
||||||
|
<!entity dropOperatorFamily system "drop_opfamily.sgml">
|
||||||
<!entity dropOwned system "drop_owned.sgml">
|
<!entity dropOwned system "drop_owned.sgml">
|
||||||
<!entity dropRole system "drop_role.sgml">
|
<!entity dropRole system "drop_role.sgml">
|
||||||
<!entity dropRule system "drop_rule.sgml">
|
<!entity dropRule system "drop_rule.sgml">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -102,6 +102,7 @@ ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="p
|
|||||||
<simplelist type="inline">
|
<simplelist type="inline">
|
||||||
<member><xref linkend="sql-createopclass" endterm="sql-createopclass-title"></member>
|
<member><xref linkend="sql-createopclass" endterm="sql-createopclass-title"></member>
|
||||||
<member><xref linkend="sql-dropopclass" endterm="sql-dropopclass-title"></member>
|
<member><xref linkend="sql-dropopclass" endterm="sql-dropopclass-title"></member>
|
||||||
|
<member><xref linkend="sql-alteropfamily" endterm="sql-alteropfamily-title"></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
|
312
doc/src/sgml/ref/alter_opfamily.sgml
Normal file
312
doc/src/sgml/ref/alter_opfamily.sgml
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
<!--
|
||||||
|
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_opfamily.sgml,v 1.1 2007/01/23 05:07:17 tgl Exp $
|
||||||
|
PostgreSQL documentation
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="SQL-ALTEROPFAMILY">
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle id="SQL-ALTEROPFAMILY-TITLE">ALTER OPERATOR FAMILY</refentrytitle>
|
||||||
|
<refmiscinfo>SQL - Language Statements</refmiscinfo>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>ALTER OPERATOR FAMILY</refname>
|
||||||
|
<refpurpose>change the definition of an operator family</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<indexterm zone="sql-alteropfamily">
|
||||||
|
<primary>ALTER OPERATOR FAMILY</primary>
|
||||||
|
</indexterm>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<synopsis>
|
||||||
|
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> ADD
|
||||||
|
{ 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">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] ) ] <replaceable class="parameter">funcname</replaceable> ( <replaceable class="parameter">argument_type</replaceable> [, ...] )
|
||||||
|
} [, ... ]
|
||||||
|
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> DROP
|
||||||
|
{ OPERATOR <replaceable class="parameter">strategy_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] )
|
||||||
|
| FUNCTION <replaceable class="parameter">support_number</replaceable> ( <replaceable class="parameter">op_type</replaceable> [ , <replaceable class="parameter">op_type</replaceable> ] )
|
||||||
|
} [, ... ]
|
||||||
|
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> RENAME TO <replaceable>newname</replaceable>
|
||||||
|
ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> OWNER TO <replaceable>newowner</replaceable>
|
||||||
|
</synopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<command>ALTER OPERATOR FAMILY</command> changes the definition of
|
||||||
|
an operator family. You can add operators and support functions
|
||||||
|
to the family, remove them from the family,
|
||||||
|
or change the family's name or owner.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When operators and support functions are added to a family with
|
||||||
|
<command>ALTER OPERATOR FAMILY</command>, they are not part of any
|
||||||
|
specific operator class within the family, but are just <quote>loose</>
|
||||||
|
within the family. This indicates that these operators and functions
|
||||||
|
are compatible with the family's semantics, but are not required for
|
||||||
|
correct functioning of any specific index. (Operators and functions
|
||||||
|
that are so required should be declared as part of an operator class,
|
||||||
|
instead; see <xref linkend="sql-createopclass"
|
||||||
|
endterm="sql-createopclass-title">.)
|
||||||
|
<productname>PostgreSQL</productname> will allow loose members of a
|
||||||
|
family to be dropped from the family at any time, but members of an
|
||||||
|
operator class cannot be dropped without dropping the whole class and
|
||||||
|
any indexes that depend on it.
|
||||||
|
Typically, single-data-type operators
|
||||||
|
and functions are part of operator classes because they are needed to
|
||||||
|
support an index on that specific data type, while cross-data-type
|
||||||
|
operators and functions are made loose members of the family.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
You must be a superuser to use <command>ALTER OPERATOR FAMILY</>.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Parameters</title>
|
||||||
|
|
||||||
|
<variablelist>
|
||||||
|
<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 method this operator family is for.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">strategy_number</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The index method's strategy number for an operator
|
||||||
|
associated with the operator family.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">operator_name</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The name (optionally schema-qualified) of an operator associated
|
||||||
|
with the operator family.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">op_type</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
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. Unlike the comparable
|
||||||
|
syntax in <command>CREATE OPERATOR CLASS</>, the operand data types
|
||||||
|
must always be specified.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In an <literal>ADD 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
|
||||||
|
it is not necessary to specify <replaceable
|
||||||
|
class="parameter">op_type</replaceable> since the function's input
|
||||||
|
data type(s) are always the correct ones to use. For GIN and GiST
|
||||||
|
indexes it is necessary to specify the input data type the function
|
||||||
|
is to be used with.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
In a <literal>DROP FUNCTION</> clause, the operand data type(s) the
|
||||||
|
function is intended to support must be specified.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>RECHECK</></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
If present, the index is <quote>lossy</> for this operator, and
|
||||||
|
so the rows retrieved using the index must be rechecked to
|
||||||
|
verify that they actually satisfy the qualification clause
|
||||||
|
involving this operator.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">support_number</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The index method's support procedure number for a
|
||||||
|
function associated with the operator family.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">funcname</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The name (optionally schema-qualified) of a function that is an
|
||||||
|
index method support procedure for the operator family.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">argument_types</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The parameter data type(s) of the function.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">newname</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The new name of the operator family.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><replaceable class="parameter">newowner</replaceable></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
The new owner of the operator family.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The <literal>OPERATOR</> and <literal>FUNCTION</>
|
||||||
|
clauses may appear in any order.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Notice that the <literal>DROP</> syntax only specifies the <quote>slot</>
|
||||||
|
in the operator family, by strategy or support number and input data
|
||||||
|
type(s). The name of the operator or function occupying the slot is not
|
||||||
|
mentioned. Also, for <literal>DROP FUNCTION</> the type(s) to specify
|
||||||
|
are the input data type(s) the function is intended to support; for
|
||||||
|
GIN and GiST indexes this may have nothing to do with the actual input
|
||||||
|
argument types of the function.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Because the index machinery does not check access permissions on functions
|
||||||
|
before using them, including a function or operator in an operator family
|
||||||
|
is tantamount to granting public execute permission on it. This is usually
|
||||||
|
not an issue for the sorts of functions that are useful in an operator
|
||||||
|
family.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The operators should not be defined by SQL functions. A SQL function
|
||||||
|
is likely to be inlined into the calling query, which will prevent
|
||||||
|
the optimizer from recognizing that the query matches an index.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Examples</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The following example command adds cross-data-type operators and
|
||||||
|
support functions to an operator family that already contains B-tree
|
||||||
|
operator classes for data types <type>int4</> and <type>int2</>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
ALTER OPERATOR FAMILY integer_ops USING btree ADD
|
||||||
|
|
||||||
|
-- int4 vs int2
|
||||||
|
OPERATOR 1 < (int4, int2) ,
|
||||||
|
OPERATOR 2 <= (int4, int2) ,
|
||||||
|
OPERATOR 3 = (int4, int2) ,
|
||||||
|
OPERATOR 4 >= (int4, int2) ,
|
||||||
|
OPERATOR 5 > (int4, int2) ,
|
||||||
|
FUNCTION 1 btint42cmp(int4, int2) ,
|
||||||
|
|
||||||
|
-- int2 vs int4
|
||||||
|
OPERATOR 1 < (int2, int4) ,
|
||||||
|
OPERATOR 2 <= (int2, int4) ,
|
||||||
|
OPERATOR 3 = (int2, int4) ,
|
||||||
|
OPERATOR 4 >= (int2, int4) ,
|
||||||
|
OPERATOR 5 > (int2, int4) ,
|
||||||
|
FUNCTION 1 btint24cmp(int2, int4) ;
|
||||||
|
</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
To remove these entries again:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>
|
||||||
|
ALTER OPERATOR FAMILY integer_ops USING btree DROP
|
||||||
|
|
||||||
|
-- int4 vs int2
|
||||||
|
OPERATOR 1 (int4, int2) ,
|
||||||
|
OPERATOR 2 (int4, int2) ,
|
||||||
|
OPERATOR 3 (int4, int2) ,
|
||||||
|
OPERATOR 4 (int4, int2) ,
|
||||||
|
OPERATOR 5 (int4, int2) ,
|
||||||
|
FUNCTION 1 (int4, int2) ,
|
||||||
|
|
||||||
|
-- int2 vs int4
|
||||||
|
OPERATOR 1 (int2, int4) ,
|
||||||
|
OPERATOR 2 (int2, int4) ,
|
||||||
|
OPERATOR 3 (int2, int4) ,
|
||||||
|
OPERATOR 4 (int2, int4) ,
|
||||||
|
OPERATOR 5 (int2, int4) ,
|
||||||
|
FUNCTION 1 (int2, int4) ;
|
||||||
|
</programlisting>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Compatibility</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
There is no <command>ALTER OPERATOR FAMILY</command> statement in
|
||||||
|
the SQL standard.
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<simplelist type="inline">
|
||||||
|
<member><xref linkend="sql-createopfamily" endterm="sql-createopfamily-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>
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -35,6 +35,7 @@ COMMENT ON
|
|||||||
LARGE OBJECT <replaceable class="PARAMETER">large_object_oid</replaceable> |
|
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 <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 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> |
|
[ PROCEDURAL ] LANGUAGE <replaceable class="PARAMETER">object_name</replaceable> |
|
||||||
ROLE <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> |
|
RULE <replaceable class="PARAMETER">rule_name</replaceable> ON <replaceable class="PARAMETER">table_name</replaceable> |
|
||||||
@ -92,7 +93,7 @@ COMMENT ON
|
|||||||
<para>
|
<para>
|
||||||
The name of the object to be commented. Names of tables,
|
The name of the object to be commented. Names of tables,
|
||||||
aggregates, domains, functions, indexes, operators, operator classes,
|
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>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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 ^ (text, text) IS 'Performs intersection of two texts';
|
||||||
COMMENT ON OPERATOR - (NONE, text) IS 'This is a prefix operator on text';
|
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 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 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 RULE my_rule ON my_table IS 'Logs updates of employee records';
|
||||||
COMMENT ON SCHEMA my_schema IS 'Departmental data';
|
COMMENT ON SCHEMA my_schema IS 'Departmental data';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -20,9 +20,10 @@ PostgreSQL documentation
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<synopsis>
|
<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 ]
|
{ 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>
|
| STORAGE <replaceable class="parameter">storage_type</replaceable>
|
||||||
} [, ... ]
|
} [, ... ]
|
||||||
</synopsis>
|
</synopsis>
|
||||||
@ -40,7 +41,7 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
|
|||||||
be used by
|
be used by
|
||||||
the index method when the operator class is selected for an
|
the index method when the operator class is selected for an
|
||||||
index column. All the operators and functions used by an operator
|
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>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -65,6 +66,15 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
|
|||||||
responsibility to define a valid operator class.
|
responsibility to define a valid operator class.
|
||||||
</para>
|
</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>
|
<para>
|
||||||
Refer to <xref linkend="xindex"> for further information.
|
Refer to <xref linkend="xindex"> for further information.
|
||||||
</para>
|
</para>
|
||||||
@ -113,6 +123,17 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><replaceable class="parameter">strategy_number</replaceable></term>
|
<term><replaceable class="parameter">strategy_number</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -137,11 +158,24 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
|
|||||||
<term><replaceable class="parameter">op_type</replaceable></term>
|
<term><replaceable class="parameter">op_type</replaceable></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<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
|
signify a left-unary or right-unary operator. The operand data
|
||||||
types may be omitted in the normal case where they are the same
|
types may be omitted in the normal case where they are the same
|
||||||
as the operator class's data type.
|
as the operator class's data type.
|
||||||
</para>
|
</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>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
@ -192,7 +226,7 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
|
|||||||
<para>
|
<para>
|
||||||
The data type actually stored in the index. Normally this is
|
The data type actually stored in the index. Normally this is
|
||||||
the same as the column data type, but some index methods
|
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
|
<literal>STORAGE</> clause must be omitted unless the index
|
||||||
method allows a different type to be used.
|
method allows a different type to be used.
|
||||||
</para>
|
</para>
|
||||||
@ -268,6 +302,8 @@ CREATE OPERATOR CLASS gist__int_ops
|
|||||||
<simplelist type="inline">
|
<simplelist type="inline">
|
||||||
<member><xref linkend="sql-alteropclass" endterm="sql-alteropclass-title"></member>
|
<member><xref linkend="sql-alteropclass" endterm="sql-alteropclass-title"></member>
|
||||||
<member><xref linkend="sql-dropopclass" endterm="sql-dropopclass-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>
|
</simplelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
</refentry>
|
</refentry>
|
||||||
|
125
doc/src/sgml/ref/create_opfamily.sgml
Normal file
125
doc/src/sgml/ref/create_opfamily.sgml
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<!--
|
||||||
|
$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>
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$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
|
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.
|
<command>DROP OPERATOR CLASS</command> drops an existing operator class.
|
||||||
To execute this command you must be the owner of the operator class.
|
To execute this command you must be the owner of the operator class.
|
||||||
</para>
|
</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>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
@ -87,6 +94,20 @@ DROP OPERATOR CLASS [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceab
|
|||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</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>
|
<refsect1>
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
|
|
||||||
@ -118,6 +139,7 @@ DROP OPERATOR CLASS widget_ops USING btree;
|
|||||||
<simplelist type="inline">
|
<simplelist type="inline">
|
||||||
<member><xref linkend="sql-alteropclass" endterm="sql-alteropclass-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-createopclass" endterm="sql-createopclass-title"></member>
|
||||||
|
<member><xref linkend="sql-dropopfamily" endterm="sql-dropopfamily-title"></member>
|
||||||
</simplelist>
|
</simplelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
135
doc/src/sgml/ref/drop_opfamily.sgml
Normal file
135
doc/src/sgml/ref/drop_opfamily.sgml
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<!--
|
||||||
|
$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>
|
@ -1,4 +1,4 @@
|
|||||||
<!-- $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">
|
<part id="reference">
|
||||||
<title>Reference</title>
|
<title>Reference</title>
|
||||||
@ -44,6 +44,7 @@
|
|||||||
&alterLanguage;
|
&alterLanguage;
|
||||||
&alterOperator;
|
&alterOperator;
|
||||||
&alterOperatorClass;
|
&alterOperatorClass;
|
||||||
|
&alterOperatorFamily;
|
||||||
&alterRole;
|
&alterRole;
|
||||||
&alterSchema;
|
&alterSchema;
|
||||||
&alterSequence;
|
&alterSequence;
|
||||||
@ -73,6 +74,7 @@
|
|||||||
&createLanguage;
|
&createLanguage;
|
||||||
&createOperator;
|
&createOperator;
|
||||||
&createOperatorClass;
|
&createOperatorClass;
|
||||||
|
&createOperatorFamily;
|
||||||
&createRole;
|
&createRole;
|
||||||
&createRule;
|
&createRule;
|
||||||
&createSchema;
|
&createSchema;
|
||||||
@ -98,6 +100,7 @@
|
|||||||
&dropLanguage;
|
&dropLanguage;
|
||||||
&dropOperator;
|
&dropOperator;
|
||||||
&dropOperatorClass;
|
&dropOperatorClass;
|
||||||
|
&dropOperatorFamily;
|
||||||
&dropOwned;
|
&dropOwned;
|
||||||
&dropRole;
|
&dropRole;
|
||||||
&dropRule;
|
&dropRule;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* See acl.h.
|
* See acl.h.
|
||||||
@ -30,6 +30,7 @@
|
|||||||
#include "catalog/pg_namespace.h"
|
#include "catalog/pg_namespace.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
|
#include "catalog/pg_opfamily.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_tablespace.h"
|
#include "catalog/pg_tablespace.h"
|
||||||
#include "catalog/pg_type.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"),
|
gettext_noop("permission denied for schema %s"),
|
||||||
/* ACL_KIND_OPCLASS */
|
/* ACL_KIND_OPCLASS */
|
||||||
gettext_noop("permission denied for operator class %s"),
|
gettext_noop("permission denied for operator class %s"),
|
||||||
|
/* ACL_KIND_OPFAMILY */
|
||||||
|
gettext_noop("permission denied for operator family %s"),
|
||||||
/* ACL_KIND_CONVERSION */
|
/* ACL_KIND_CONVERSION */
|
||||||
gettext_noop("permission denied for conversion %s"),
|
gettext_noop("permission denied for conversion %s"),
|
||||||
/* ACL_KIND_TABLESPACE */
|
/* 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"),
|
gettext_noop("must be owner of schema %s"),
|
||||||
/* ACL_KIND_OPCLASS */
|
/* ACL_KIND_OPCLASS */
|
||||||
gettext_noop("must be owner of operator class %s"),
|
gettext_noop("must be owner of operator class %s"),
|
||||||
|
/* ACL_KIND_OPFAMILY */
|
||||||
|
gettext_noop("must be owner of operator family %s"),
|
||||||
/* ACL_KIND_CONVERSION */
|
/* ACL_KIND_CONVERSION */
|
||||||
gettext_noop("must be owner of conversion %s"),
|
gettext_noop("must be owner of conversion %s"),
|
||||||
/* ACL_KIND_TABLESPACE */
|
/* ACL_KIND_TABLESPACE */
|
||||||
@ -2239,6 +2244,35 @@ pg_opclass_ownercheck(Oid opc_oid, Oid roleid)
|
|||||||
return has_privs_of_role(roleid, ownerId);
|
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).
|
* Ownership check for a database (specified by OID).
|
||||||
*/
|
*/
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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);
|
RenameOpClass(stmt->object, stmt->subname, stmt->newname);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OBJECT_OPFAMILY:
|
||||||
|
RenameOpFamily(stmt->object, stmt->subname, stmt->newname);
|
||||||
|
break;
|
||||||
|
|
||||||
case OBJECT_ROLE:
|
case OBJECT_ROLE:
|
||||||
RenameRole(stmt->subname, stmt->newname);
|
RenameRole(stmt->subname, stmt->newname);
|
||||||
break;
|
break;
|
||||||
@ -211,6 +215,10 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
|
|||||||
AlterOpClassOwner(stmt->object, stmt->addname, newowner);
|
AlterOpClassOwner(stmt->object, stmt->addname, newowner);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OBJECT_OPFAMILY:
|
||||||
|
AlterOpFamilyOwner(stmt->object, stmt->addname, newowner);
|
||||||
|
break;
|
||||||
|
|
||||||
case OBJECT_SCHEMA:
|
case OBJECT_SCHEMA:
|
||||||
AlterSchemaOwner((char *) linitial(stmt->object), newowner);
|
AlterSchemaOwner((char *) linitial(stmt->object), newowner);
|
||||||
break;
|
break;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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_namespace.h"
|
||||||
#include "catalog/pg_opclass.h"
|
#include "catalog/pg_opclass.h"
|
||||||
#include "catalog/pg_operator.h"
|
#include "catalog/pg_operator.h"
|
||||||
|
#include "catalog/pg_opfamily.h"
|
||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "catalog/pg_rewrite.h"
|
#include "catalog/pg_rewrite.h"
|
||||||
#include "catalog/pg_shdescription.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 CommentConversion(List *qualname, char *comment);
|
||||||
static void CommentLanguage(List *qualname, char *comment);
|
static void CommentLanguage(List *qualname, char *comment);
|
||||||
static void CommentOpClass(List *qualname, List *arguments, 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 CommentLargeObject(List *qualname, char *comment);
|
||||||
static void CommentCast(List *qualname, List *arguments, char *comment);
|
static void CommentCast(List *qualname, List *arguments, char *comment);
|
||||||
static void CommentTablespace(List *qualname, char *comment);
|
static void CommentTablespace(List *qualname, char *comment);
|
||||||
@ -134,6 +136,9 @@ CommentObject(CommentStmt *stmt)
|
|||||||
case OBJECT_OPCLASS:
|
case OBJECT_OPCLASS:
|
||||||
CommentOpClass(stmt->objname, stmt->objargs, stmt->comment);
|
CommentOpClass(stmt->objname, stmt->objargs, stmt->comment);
|
||||||
break;
|
break;
|
||||||
|
case OBJECT_OPFAMILY:
|
||||||
|
CommentOpFamily(stmt->objname, stmt->objargs, stmt->comment);
|
||||||
|
break;
|
||||||
case OBJECT_LARGEOBJECT:
|
case OBJECT_LARGEOBJECT:
|
||||||
CommentLargeObject(stmt->objname, stmt->comment);
|
CommentLargeObject(stmt->objname, stmt->comment);
|
||||||
break;
|
break;
|
||||||
@ -1263,6 +1268,92 @@ CommentOpClass(List *qualname, List *arguments, char *comment)
|
|||||||
CreateComments(opcID, OperatorClassRelationId, 0, 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 --
|
* CommentLargeObject --
|
||||||
*
|
*
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.52 2007/01/05 22:19:26 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/opclasscmds.c,v 1.53 2007/01/23 05:07:17 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -55,15 +55,30 @@ typedef struct
|
|||||||
} OpFamilyMember;
|
} OpFamilyMember;
|
||||||
|
|
||||||
|
|
||||||
|
static void AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
||||||
|
int maxOpNumber, int maxProcNumber,
|
||||||
|
List *items);
|
||||||
|
static void AlterOpFamilyDrop(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
||||||
|
int maxOpNumber, int maxProcNumber,
|
||||||
|
List *items);
|
||||||
|
static void processTypesSpec(List *args, Oid *lefttype, Oid *righttype);
|
||||||
static void assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid);
|
static void assignOperTypes(OpFamilyMember *member, Oid amoid, Oid typeoid);
|
||||||
static void assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid);
|
static void assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid);
|
||||||
static void addFamilyMember(List **list, OpFamilyMember *member, bool isProc);
|
static void addFamilyMember(List **list, OpFamilyMember *member, bool isProc);
|
||||||
static void storeOperators(Oid amoid, Oid opfamilyoid, Oid opclassoid,
|
static void storeOperators(List *opfamilyname, Oid amoid,
|
||||||
|
Oid opfamilyoid, Oid opclassoid,
|
||||||
|
List *operators, bool isAdd);
|
||||||
|
static void storeProcedures(List *opfamilyname, Oid amoid,
|
||||||
|
Oid opfamilyoid, Oid opclassoid,
|
||||||
|
List *procedures, bool isAdd);
|
||||||
|
static void dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
||||||
List *operators);
|
List *operators);
|
||||||
static void storeProcedures(Oid amoid, Oid opfamilyoid, Oid opclassoid,
|
static void dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
||||||
List *procedures);
|
List *procedures);
|
||||||
static void AlterOpClassOwner_internal(Relation rel, HeapTuple tuple,
|
static void AlterOpClassOwner_internal(Relation rel, HeapTuple tuple,
|
||||||
Oid newOwnerId);
|
Oid newOwnerId);
|
||||||
|
static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple,
|
||||||
|
Oid newOwnerId);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -452,6 +467,12 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
|||||||
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
||||||
member->object = funcOid;
|
member->object = funcOid;
|
||||||
member->number = item->number;
|
member->number = item->number;
|
||||||
|
|
||||||
|
/* allow overriding of the function's actual arg types */
|
||||||
|
if (item->class_args)
|
||||||
|
processTypesSpec(item->class_args,
|
||||||
|
&member->lefttype, &member->righttype);
|
||||||
|
|
||||||
assignProcTypes(member, amoid, typeoid);
|
assignProcTypes(member, amoid, typeoid);
|
||||||
addFamilyMember(&procedures, member, true);
|
addFamilyMember(&procedures, member, true);
|
||||||
break;
|
break;
|
||||||
@ -570,8 +591,10 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
|||||||
* Now add tuples to pg_amop and pg_amproc tying in the operators and
|
* Now add tuples to pg_amop and pg_amproc tying in the operators and
|
||||||
* functions. Dependencies on them are inserted, too.
|
* functions. Dependencies on them are inserted, too.
|
||||||
*/
|
*/
|
||||||
storeOperators(amoid, opfamilyoid, opclassoid, operators);
|
storeOperators(stmt->opfamilyname, amoid, opfamilyoid,
|
||||||
storeProcedures(amoid, opfamilyoid, opclassoid, procedures);
|
opclassoid, operators, false);
|
||||||
|
storeProcedures(stmt->opfamilyname, amoid, opfamilyoid,
|
||||||
|
opclassoid, procedures, false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create dependencies for the opclass proper. Note: we do not create a
|
* Create dependencies for the opclass proper. Note: we do not create a
|
||||||
@ -615,6 +638,420 @@ DefineOpClass(CreateOpClassStmt *stmt)
|
|||||||
heap_close(rel, RowExclusiveLock);
|
heap_close(rel, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DefineOpFamily
|
||||||
|
* Define a new index operator family.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
DefineOpFamily(CreateOpFamilyStmt *stmt)
|
||||||
|
{
|
||||||
|
char *opfname; /* name of opfamily we're creating */
|
||||||
|
Oid amoid, /* our AM's oid */
|
||||||
|
namespaceoid, /* namespace to create opfamily in */
|
||||||
|
opfamilyoid; /* oid of opfamily we create */
|
||||||
|
Relation rel;
|
||||||
|
HeapTuple tup;
|
||||||
|
Datum values[Natts_pg_opfamily];
|
||||||
|
char nulls[Natts_pg_opfamily];
|
||||||
|
AclResult aclresult;
|
||||||
|
NameData opfName;
|
||||||
|
ObjectAddress myself,
|
||||||
|
referenced;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
|
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||||
|
get_namespace_name(namespaceoid));
|
||||||
|
|
||||||
|
/* Get necessary info about access method */
|
||||||
|
tup = SearchSysCache(AMNAME,
|
||||||
|
CStringGetDatum(stmt->amname),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("access method \"%s\" does not exist",
|
||||||
|
stmt->amname)));
|
||||||
|
|
||||||
|
amoid = HeapTupleGetOid(tup);
|
||||||
|
|
||||||
|
/* XXX Should we make any privilege check against the AM? */
|
||||||
|
|
||||||
|
ReleaseSysCache(tup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently, we require superuser privileges to create an opfamily.
|
||||||
|
* See comments in DefineOpClass.
|
||||||
|
*
|
||||||
|
* XXX re-enable NOT_USED code sections below if you remove this test.
|
||||||
|
*/
|
||||||
|
if (!superuser())
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
|
errmsg("must be superuser to create an operator family")));
|
||||||
|
|
||||||
|
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure there is no existing opfamily of this name (this is just to
|
||||||
|
* give a more friendly error message than "duplicate key").
|
||||||
|
*/
|
||||||
|
if (SearchSysCacheExists(OPFAMILYAMNAMENSP,
|
||||||
|
ObjectIdGetDatum(amoid),
|
||||||
|
CStringGetDatum(opfname),
|
||||||
|
ObjectIdGetDatum(namespaceoid),
|
||||||
|
0))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" for access method \"%s\" already exists",
|
||||||
|
opfname, stmt->amname)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Okay, let's create the pg_opfamily entry.
|
||||||
|
*/
|
||||||
|
memset(values, 0, sizeof(values));
|
||||||
|
memset(nulls, ' ', sizeof(nulls));
|
||||||
|
|
||||||
|
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());
|
||||||
|
|
||||||
|
tup = heap_formtuple(rel->rd_att, values, nulls);
|
||||||
|
|
||||||
|
opfamilyoid = simple_heap_insert(rel, tup);
|
||||||
|
|
||||||
|
CatalogUpdateIndexes(rel, tup);
|
||||||
|
|
||||||
|
heap_freetuple(tup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create dependencies for the opfamily proper. Note: we do not create a
|
||||||
|
* dependency link to the AM, because we don't currently support DROP
|
||||||
|
* ACCESS METHOD.
|
||||||
|
*/
|
||||||
|
myself.classId = OperatorFamilyRelationId;
|
||||||
|
myself.objectId = opfamilyoid;
|
||||||
|
myself.objectSubId = 0;
|
||||||
|
|
||||||
|
/* dependency on namespace */
|
||||||
|
referenced.classId = NamespaceRelationId;
|
||||||
|
referenced.objectId = namespaceoid;
|
||||||
|
referenced.objectSubId = 0;
|
||||||
|
recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
|
||||||
|
|
||||||
|
/* dependency on owner */
|
||||||
|
recordDependencyOnOwner(OperatorFamilyRelationId, opfamilyoid, GetUserId());
|
||||||
|
|
||||||
|
heap_close(rel, RowExclusiveLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlterOpFamily(AlterOpFamilyStmt *stmt)
|
||||||
|
{
|
||||||
|
Oid amoid, /* our AM's oid */
|
||||||
|
opfamilyoid; /* oid of opfamily */
|
||||||
|
int maxOpNumber, /* amstrategies value */
|
||||||
|
maxProcNumber; /* amsupport value */
|
||||||
|
HeapTuple tup;
|
||||||
|
Form_pg_am pg_am;
|
||||||
|
|
||||||
|
/* Get necessary info about access method */
|
||||||
|
tup = SearchSysCache(AMNAME,
|
||||||
|
CStringGetDatum(stmt->amname),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("access method \"%s\" does not exist",
|
||||||
|
stmt->amname)));
|
||||||
|
|
||||||
|
amoid = HeapTupleGetOid(tup);
|
||||||
|
pg_am = (Form_pg_am) GETSTRUCT(tup);
|
||||||
|
maxOpNumber = pg_am->amstrategies;
|
||||||
|
/* if amstrategies is zero, just enforce that op numbers fit in int16 */
|
||||||
|
if (maxOpNumber <= 0)
|
||||||
|
maxOpNumber = SHRT_MAX;
|
||||||
|
maxProcNumber = pg_am->amsupport;
|
||||||
|
|
||||||
|
/* XXX Should we make any privilege check against the AM? */
|
||||||
|
|
||||||
|
ReleaseSysCache(tup);
|
||||||
|
|
||||||
|
/* Look up the opfamily */
|
||||||
|
tup = OpFamilyCacheLookup(amoid, stmt->opfamilyname);
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
||||||
|
NameListToString(stmt->opfamilyname), stmt->amname)));
|
||||||
|
opfamilyoid = HeapTupleGetOid(tup);
|
||||||
|
ReleaseSysCache(tup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently, we require superuser privileges to alter an opfamily.
|
||||||
|
*
|
||||||
|
* XXX re-enable NOT_USED code sections below if you remove this test.
|
||||||
|
*/
|
||||||
|
if (!superuser())
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
|
errmsg("must be superuser to alter an operator family")));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADD and DROP cases need separate code from here on down.
|
||||||
|
*/
|
||||||
|
if (stmt->isDrop)
|
||||||
|
AlterOpFamilyDrop(stmt->opfamilyname, amoid, opfamilyoid,
|
||||||
|
maxOpNumber, maxProcNumber,
|
||||||
|
stmt->items);
|
||||||
|
else
|
||||||
|
AlterOpFamilyAdd(stmt->opfamilyname, amoid, opfamilyoid,
|
||||||
|
maxOpNumber, maxProcNumber,
|
||||||
|
stmt->items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADD part of ALTER OP FAMILY
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AlterOpFamilyAdd(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
||||||
|
int maxOpNumber, int maxProcNumber,
|
||||||
|
List *items)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
CreateOpClassItem *item = lfirst(l);
|
||||||
|
Oid operOid;
|
||||||
|
Oid funcOid;
|
||||||
|
OpFamilyMember *member;
|
||||||
|
|
||||||
|
Assert(IsA(item, CreateOpClassItem));
|
||||||
|
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)));
|
||||||
|
if (item->args != NIL)
|
||||||
|
{
|
||||||
|
TypeName *typeName1 = (TypeName *) linitial(item->args);
|
||||||
|
TypeName *typeName2 = (TypeName *) lsecond(item->args);
|
||||||
|
|
||||||
|
operOid = LookupOperNameTypeNames(NULL, item->name,
|
||||||
|
typeName1, typeName2,
|
||||||
|
false, -1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("operator argument types must be specified in ALTER OPERATOR FAMILY")));
|
||||||
|
operOid = InvalidOid; /* keep compiler quiet */
|
||||||
|
}
|
||||||
|
|
||||||
|
#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()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER,
|
||||||
|
get_opname(operOid));
|
||||||
|
funcOid = get_opcode(operOid);
|
||||||
|
if (!pg_proc_ownercheck(funcOid, GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
|
||||||
|
get_func_name(funcOid));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Save the info */
|
||||||
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
||||||
|
member->object = operOid;
|
||||||
|
member->number = item->number;
|
||||||
|
member->recheck = item->recheck;
|
||||||
|
assignOperTypes(member, amoid, InvalidOid);
|
||||||
|
addFamilyMember(&operators, member, false);
|
||||||
|
break;
|
||||||
|
case OPCLASS_ITEM_FUNCTION:
|
||||||
|
if (item->number <= 0 || item->number > maxProcNumber)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("invalid procedure number %d,"
|
||||||
|
" must be between 1 and %d",
|
||||||
|
item->number, maxProcNumber)));
|
||||||
|
funcOid = LookupFuncNameTypeNames(item->name, item->args,
|
||||||
|
false);
|
||||||
|
#ifdef NOT_USED
|
||||||
|
/* XXX this is unnecessary given the superuser check above */
|
||||||
|
/* Caller must own function */
|
||||||
|
if (!pg_proc_ownercheck(funcOid, GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
|
||||||
|
get_func_name(funcOid));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Save the info */
|
||||||
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
||||||
|
member->object = funcOid;
|
||||||
|
member->number = item->number;
|
||||||
|
|
||||||
|
/* allow overriding of the function's actual arg types */
|
||||||
|
if (item->class_args)
|
||||||
|
processTypesSpec(item->class_args,
|
||||||
|
&member->lefttype, &member->righttype);
|
||||||
|
|
||||||
|
assignProcTypes(member, amoid, InvalidOid);
|
||||||
|
addFamilyMember(&procedures, member, true);
|
||||||
|
break;
|
||||||
|
case OPCLASS_ITEM_STORAGETYPE:
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
|
errmsg("STORAGE may not be specified in ALTER OPERATOR FAMILY")));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unrecognized item type: %d", item->itemtype);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add tuples to pg_amop and pg_amproc tying in the operators and
|
||||||
|
* functions. Dependencies on them are inserted, too.
|
||||||
|
*/
|
||||||
|
storeOperators(opfamilyname, amoid, opfamilyoid,
|
||||||
|
InvalidOid, operators, true);
|
||||||
|
storeProcedures(opfamilyname, amoid, opfamilyoid,
|
||||||
|
InvalidOid, procedures, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DROP part of ALTER OP FAMILY
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AlterOpFamilyDrop(List *opfamilyname, Oid amoid, Oid opfamilyoid,
|
||||||
|
int maxOpNumber, int maxProcNumber,
|
||||||
|
List *items)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
CreateOpClassItem *item = lfirst(l);
|
||||||
|
Oid lefttype,
|
||||||
|
righttype;
|
||||||
|
OpFamilyMember *member;
|
||||||
|
|
||||||
|
Assert(IsA(item, CreateOpClassItem));
|
||||||
|
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)));
|
||||||
|
processTypesSpec(item->args, &lefttype, &righttype);
|
||||||
|
/* Save the info */
|
||||||
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
||||||
|
member->number = item->number;
|
||||||
|
member->lefttype = lefttype;
|
||||||
|
member->righttype = righttype;
|
||||||
|
addFamilyMember(&operators, member, false);
|
||||||
|
break;
|
||||||
|
case OPCLASS_ITEM_FUNCTION:
|
||||||
|
if (item->number <= 0 || item->number > maxProcNumber)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
|
||||||
|
errmsg("invalid procedure number %d,"
|
||||||
|
" must be between 1 and %d",
|
||||||
|
item->number, maxProcNumber)));
|
||||||
|
processTypesSpec(item->args, &lefttype, &righttype);
|
||||||
|
/* Save the info */
|
||||||
|
member = (OpFamilyMember *) palloc0(sizeof(OpFamilyMember));
|
||||||
|
member->number = item->number;
|
||||||
|
member->lefttype = lefttype;
|
||||||
|
member->righttype = righttype;
|
||||||
|
addFamilyMember(&procedures, member, true);
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
dropOperators(opfamilyname, amoid, opfamilyoid, operators);
|
||||||
|
dropProcedures(opfamilyname, amoid, opfamilyoid, procedures);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
*lefttype = typenameTypeId(NULL, typeName);
|
||||||
|
|
||||||
|
if (list_length(args) > 1)
|
||||||
|
{
|
||||||
|
typeName = (TypeName *) lsecond(args);
|
||||||
|
*righttype = typenameTypeId(NULL, typeName);
|
||||||
|
}
|
||||||
|
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,
|
* Determine the lefttype/righttype to assign to an operator,
|
||||||
* and do any validity checking we can manage.
|
* and do any validity checking we can manage.
|
||||||
@ -781,7 +1218,9 @@ addFamilyMember(List **list, OpFamilyMember *member, bool isProc)
|
|||||||
* else make an AUTO dependency on the opfamily.
|
* else make an AUTO dependency on the opfamily.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
storeOperators(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *operators)
|
storeOperators(List *opfamilyname, Oid amoid,
|
||||||
|
Oid opfamilyoid, Oid opclassoid,
|
||||||
|
List *operators, bool isAdd)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
Datum values[Natts_pg_amop];
|
Datum values[Natts_pg_amop];
|
||||||
@ -798,6 +1237,24 @@ storeOperators(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *operators)
|
|||||||
{
|
{
|
||||||
OpFamilyMember *op = (OpFamilyMember *) lfirst(l);
|
OpFamilyMember *op = (OpFamilyMember *) lfirst(l);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If adding to an existing family, check for conflict with an
|
||||||
|
* existing pg_amop entry (just to give a nicer error message)
|
||||||
|
*/
|
||||||
|
if (isAdd &&
|
||||||
|
SearchSysCacheExists(AMOPSTRATEGY,
|
||||||
|
ObjectIdGetDatum(opfamilyoid),
|
||||||
|
ObjectIdGetDatum(op->lefttype),
|
||||||
|
ObjectIdGetDatum(op->righttype),
|
||||||
|
Int16GetDatum(op->number)))
|
||||||
|
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))));
|
||||||
|
|
||||||
/* Create the pg_amop entry */
|
/* Create the pg_amop entry */
|
||||||
memset(values, 0, sizeof(values));
|
memset(values, 0, sizeof(values));
|
||||||
memset(nulls, ' ', sizeof(nulls));
|
memset(nulls, ' ', sizeof(nulls));
|
||||||
@ -862,7 +1319,9 @@ storeOperators(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *operators)
|
|||||||
* else make an AUTO dependency on the opfamily.
|
* else make an AUTO dependency on the opfamily.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
storeProcedures(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *procedures)
|
storeProcedures(List *opfamilyname, Oid amoid,
|
||||||
|
Oid opfamilyoid, Oid opclassoid,
|
||||||
|
List *procedures, bool isAdd)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
Datum values[Natts_pg_amproc];
|
Datum values[Natts_pg_amproc];
|
||||||
@ -879,6 +1338,24 @@ storeProcedures(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *procedures)
|
|||||||
{
|
{
|
||||||
OpFamilyMember *proc = (OpFamilyMember *) lfirst(l);
|
OpFamilyMember *proc = (OpFamilyMember *) lfirst(l);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If adding to an existing family, check for conflict with an
|
||||||
|
* existing pg_amproc entry (just to give a nicer error message)
|
||||||
|
*/
|
||||||
|
if (isAdd &&
|
||||||
|
SearchSysCacheExists(AMPROCNUM,
|
||||||
|
ObjectIdGetDatum(opfamilyoid),
|
||||||
|
ObjectIdGetDatum(proc->lefttype),
|
||||||
|
ObjectIdGetDatum(proc->righttype),
|
||||||
|
Int16GetDatum(proc->number)))
|
||||||
|
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))));
|
||||||
|
|
||||||
/* Create the pg_amproc entry */
|
/* Create the pg_amproc entry */
|
||||||
memset(values, 0, sizeof(values));
|
memset(values, 0, sizeof(values));
|
||||||
memset(nulls, ' ', sizeof(nulls));
|
memset(nulls, ' ', sizeof(nulls));
|
||||||
@ -934,6 +1411,87 @@ storeProcedures(Oid amoid, Oid opfamilyoid, Oid opclassoid, List *procedures)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
amopid = GetSysCacheOid(AMOPSTRATEGY,
|
||||||
|
ObjectIdGetDatum(opfamilyoid),
|
||||||
|
ObjectIdGetDatum(op->lefttype),
|
||||||
|
ObjectIdGetDatum(op->righttype),
|
||||||
|
Int16GetDatum(op->number));
|
||||||
|
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;
|
||||||
|
|
||||||
|
performDeletion(&object, DROP_RESTRICT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
amprocid = GetSysCacheOid(AMPROCNUM,
|
||||||
|
ObjectIdGetDatum(opfamilyoid),
|
||||||
|
ObjectIdGetDatum(op->lefttype),
|
||||||
|
ObjectIdGetDatum(op->righttype),
|
||||||
|
Int16GetDatum(op->number));
|
||||||
|
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;
|
||||||
|
|
||||||
|
performDeletion(&object, DROP_RESTRICT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RemoveOpClass
|
* RemoveOpClass
|
||||||
* Deletes an opclass.
|
* Deletes an opclass.
|
||||||
@ -997,6 +1555,70 @@ RemoveOpClass(RemoveOpClassStmt *stmt)
|
|||||||
performDeletion(&object, stmt->behavior);
|
performDeletion(&object, stmt->behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RemoveOpFamily
|
||||||
|
* Deletes an opfamily.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
RemoveOpFamily(RemoveOpFamilyStmt *stmt)
|
||||||
|
{
|
||||||
|
Oid amID,
|
||||||
|
opfID;
|
||||||
|
HeapTuple tuple;
|
||||||
|
ObjectAddress object;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the access method's OID.
|
||||||
|
*/
|
||||||
|
amID = GetSysCacheOid(AMNAME,
|
||||||
|
CStringGetDatum(stmt->amname),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!OidIsValid(amID))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("access method \"%s\" does not exist",
|
||||||
|
stmt->amname)));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the opfamily.
|
||||||
|
*/
|
||||||
|
tuple = OpFamilyCacheLookup(amID, stmt->opfamilyname);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
{
|
||||||
|
if (!stmt->missing_ok)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
||||||
|
NameListToString(stmt->opfamilyname), stmt->amname)));
|
||||||
|
else
|
||||||
|
ereport(NOTICE,
|
||||||
|
(errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
||||||
|
NameListToString(stmt->opfamilyname), stmt->amname)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
opfID = HeapTupleGetOid(tuple);
|
||||||
|
|
||||||
|
/* Permission check: must own opfamily or its namespace */
|
||||||
|
if (!pg_opfamily_ownercheck(opfID, GetUserId()) &&
|
||||||
|
!pg_namespace_ownercheck(((Form_pg_opfamily) GETSTRUCT(tuple))->opfnamespace,
|
||||||
|
GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
|
||||||
|
NameListToString(stmt->opfamilyname));
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the deletion
|
||||||
|
*/
|
||||||
|
object.classId = OperatorFamilyRelationId;
|
||||||
|
object.objectId = opfID;
|
||||||
|
object.objectSubId = 0;
|
||||||
|
|
||||||
|
performDeletion(&object, stmt->behavior);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deletion subroutines for use by dependency.c.
|
* Deletion subroutines for use by dependency.c.
|
||||||
*/
|
*/
|
||||||
@ -1202,29 +1824,104 @@ RenameOpClass(List *name, const char *access_method, const char *newname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change opclass owner by oid
|
* Rename opfamily
|
||||||
*/
|
*/
|
||||||
#ifdef NOT_USED
|
|
||||||
void
|
void
|
||||||
AlterOpClassOwner_oid(Oid opcOid, Oid newOwnerId)
|
RenameOpFamily(List *name, const char *access_method, const char *newname)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Oid opfOid;
|
||||||
|
Oid amOid;
|
||||||
|
Oid namespaceOid;
|
||||||
|
char *schemaname;
|
||||||
|
char *opfname;
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
|
Relation rel;
|
||||||
|
AclResult aclresult;
|
||||||
|
|
||||||
rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
|
amOid = GetSysCacheOid(AMNAME,
|
||||||
|
CStringGetDatum(access_method),
|
||||||
tup = SearchSysCacheCopy(CLAOID,
|
|
||||||
ObjectIdGetDatum(opcOid),
|
|
||||||
0, 0, 0);
|
0, 0, 0);
|
||||||
if (!HeapTupleIsValid(tup)) /* shouldn't happen */
|
if (!OidIsValid(amOid))
|
||||||
elog(ERROR, "cache lookup failed for opclass %u", opcOid);
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("access method \"%s\" does not exist",
|
||||||
|
access_method)));
|
||||||
|
|
||||||
AlterOpClassOwner_internal(rel, tup, newOwnerId);
|
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the opfamily
|
||||||
|
*/
|
||||||
|
DeconstructQualifiedName(name, &schemaname, &opfname);
|
||||||
|
|
||||||
|
if (schemaname)
|
||||||
|
{
|
||||||
|
namespaceOid = LookupExplicitNamespace(schemaname);
|
||||||
|
|
||||||
|
tup = SearchSysCacheCopy(OPFAMILYAMNAMENSP,
|
||||||
|
ObjectIdGetDatum(amOid),
|
||||||
|
PointerGetDatum(opfname),
|
||||||
|
ObjectIdGetDatum(namespaceOid),
|
||||||
|
0);
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
||||||
|
opfname, access_method)));
|
||||||
|
|
||||||
|
opfOid = HeapTupleGetOid(tup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
opfOid = OpfamilynameGetOpfid(amOid, opfname);
|
||||||
|
if (!OidIsValid(opfOid))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
||||||
|
opfname, access_method)));
|
||||||
|
|
||||||
|
tup = SearchSysCacheCopy(OPFAMILYOID,
|
||||||
|
ObjectIdGetDatum(opfOid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tup)) /* should not happen */
|
||||||
|
elog(ERROR, "cache lookup failed for opfamily %u", opfOid);
|
||||||
|
|
||||||
|
namespaceOid = ((Form_pg_opfamily) GETSTRUCT(tup))->opfnamespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure the new name doesn't exist */
|
||||||
|
if (SearchSysCacheExists(OPFAMILYAMNAMENSP,
|
||||||
|
ObjectIdGetDatum(amOid),
|
||||||
|
CStringGetDatum(newname),
|
||||||
|
ObjectIdGetDatum(namespaceOid),
|
||||||
|
0))
|
||||||
|
{
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_DUPLICATE_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" for access method \"%s\" already exists in schema \"%s\"",
|
||||||
|
newname, access_method,
|
||||||
|
get_namespace_name(namespaceOid))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* must be owner */
|
||||||
|
if (!pg_opfamily_ownercheck(opfOid, GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
|
||||||
|
NameListToString(name));
|
||||||
|
|
||||||
|
/* must have CREATE privilege on namespace */
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceOid, GetUserId(), ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||||
|
get_namespace_name(namespaceOid));
|
||||||
|
|
||||||
|
/* rename */
|
||||||
|
namestrcpy(&(((Form_pg_opfamily) GETSTRUCT(tup))->opfname), newname);
|
||||||
|
simple_heap_update(rel, &tup->t_self, tup);
|
||||||
|
CatalogUpdateIndexes(rel, tup);
|
||||||
|
|
||||||
heap_freetuple(tup);
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
|
heap_freetuple(tup);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change opclass owner by name
|
* Change opclass owner by name
|
||||||
@ -1352,3 +2049,130 @@ AlterOpClassOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
|
|||||||
newOwnerId);
|
newOwnerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change opfamily owner by name
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId)
|
||||||
|
{
|
||||||
|
Oid amOid;
|
||||||
|
Relation rel;
|
||||||
|
HeapTuple tup;
|
||||||
|
char *opfname;
|
||||||
|
char *schemaname;
|
||||||
|
|
||||||
|
amOid = GetSysCacheOid(AMNAME,
|
||||||
|
CStringGetDatum(access_method),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!OidIsValid(amOid))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("access method \"%s\" does not exist",
|
||||||
|
access_method)));
|
||||||
|
|
||||||
|
rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the opfamily
|
||||||
|
*/
|
||||||
|
DeconstructQualifiedName(name, &schemaname, &opfname);
|
||||||
|
|
||||||
|
if (schemaname)
|
||||||
|
{
|
||||||
|
Oid namespaceOid;
|
||||||
|
|
||||||
|
namespaceOid = LookupExplicitNamespace(schemaname);
|
||||||
|
|
||||||
|
tup = SearchSysCacheCopy(OPFAMILYAMNAMENSP,
|
||||||
|
ObjectIdGetDatum(amOid),
|
||||||
|
PointerGetDatum(opfname),
|
||||||
|
ObjectIdGetDatum(namespaceOid),
|
||||||
|
0);
|
||||||
|
if (!HeapTupleIsValid(tup))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
||||||
|
opfname, access_method)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Oid opfOid;
|
||||||
|
|
||||||
|
opfOid = OpfamilynameGetOpfid(amOid, opfname);
|
||||||
|
if (!OidIsValid(opfOid))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT),
|
||||||
|
errmsg("operator family \"%s\" does not exist for access method \"%s\"",
|
||||||
|
opfname, access_method)));
|
||||||
|
|
||||||
|
tup = SearchSysCacheCopy(OPFAMILYOID,
|
||||||
|
ObjectIdGetDatum(opfOid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tup)) /* should not happen */
|
||||||
|
elog(ERROR, "cache lookup failed for opfamily %u", opfOid);
|
||||||
|
}
|
||||||
|
|
||||||
|
AlterOpFamilyOwner_internal(rel, tup, newOwnerId);
|
||||||
|
|
||||||
|
heap_freetuple(tup);
|
||||||
|
heap_close(rel, NoLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The first parameter is pg_opfamily, opened and suitably locked. The second
|
||||||
|
* parameter is a copy of the tuple from pg_opfamily we want to modify.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
AlterOpFamilyOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
|
||||||
|
{
|
||||||
|
Oid namespaceOid;
|
||||||
|
AclResult aclresult;
|
||||||
|
Form_pg_opfamily opfForm;
|
||||||
|
|
||||||
|
Assert(tup->t_tableOid == OperatorFamilyRelationId);
|
||||||
|
Assert(RelationGetRelid(rel) == OperatorFamilyRelationId);
|
||||||
|
|
||||||
|
opfForm = (Form_pg_opfamily) GETSTRUCT(tup);
|
||||||
|
|
||||||
|
namespaceOid = opfForm->opfnamespace;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the new owner is the same as the existing owner, consider the
|
||||||
|
* command to have succeeded. This is for dump restoration purposes.
|
||||||
|
*/
|
||||||
|
if (opfForm->opfowner != newOwnerId)
|
||||||
|
{
|
||||||
|
/* Superusers can always do it */
|
||||||
|
if (!superuser())
|
||||||
|
{
|
||||||
|
/* Otherwise, must be owner of the existing object */
|
||||||
|
if (!pg_opfamily_ownercheck(HeapTupleGetOid(tup), GetUserId()))
|
||||||
|
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY,
|
||||||
|
NameStr(opfForm->opfname));
|
||||||
|
|
||||||
|
/* Must be able to become new owner */
|
||||||
|
check_is_member_of_role(GetUserId(), newOwnerId);
|
||||||
|
|
||||||
|
/* New owner must have CREATE privilege on namespace */
|
||||||
|
aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId,
|
||||||
|
ACL_CREATE);
|
||||||
|
if (aclresult != ACLCHECK_OK)
|
||||||
|
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||||
|
get_namespace_name(namespaceOid));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Modify the owner --- okay to scribble on tup because it's a copy
|
||||||
|
*/
|
||||||
|
opfForm->opfowner = newOwnerId;
|
||||||
|
|
||||||
|
simple_heap_update(rel, &tup->t_self, tup);
|
||||||
|
|
||||||
|
CatalogUpdateIndexes(rel, tup);
|
||||||
|
|
||||||
|
/* Update owner dependency reference */
|
||||||
|
changeDependencyOnOwner(OperatorFamilyRelationId, HeapTupleGetOid(tup),
|
||||||
|
newOwnerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
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 *
|
static RenameStmt *
|
||||||
_copyRenameStmt(RenameStmt *from)
|
_copyRenameStmt(RenameStmt *from)
|
||||||
{
|
{
|
||||||
@ -2332,11 +2345,36 @@ _copyCreateOpClassItem(CreateOpClassItem *from)
|
|||||||
COPY_NODE_FIELD(args);
|
COPY_NODE_FIELD(args);
|
||||||
COPY_SCALAR_FIELD(number);
|
COPY_SCALAR_FIELD(number);
|
||||||
COPY_SCALAR_FIELD(recheck);
|
COPY_SCALAR_FIELD(recheck);
|
||||||
|
COPY_NODE_FIELD(class_args);
|
||||||
COPY_NODE_FIELD(storedtype);
|
COPY_NODE_FIELD(storedtype);
|
||||||
|
|
||||||
return newnode;
|
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 *
|
static CreatedbStmt *
|
||||||
_copyCreatedbStmt(CreatedbStmt *from)
|
_copyCreatedbStmt(CreatedbStmt *from)
|
||||||
{
|
{
|
||||||
@ -3163,6 +3201,9 @@ copyObject(void *from)
|
|||||||
case T_RemoveOpClassStmt:
|
case T_RemoveOpClassStmt:
|
||||||
retval = _copyRemoveOpClassStmt(from);
|
retval = _copyRemoveOpClassStmt(from);
|
||||||
break;
|
break;
|
||||||
|
case T_RemoveOpFamilyStmt:
|
||||||
|
retval = _copyRemoveOpFamilyStmt(from);
|
||||||
|
break;
|
||||||
case T_RenameStmt:
|
case T_RenameStmt:
|
||||||
retval = _copyRenameStmt(from);
|
retval = _copyRenameStmt(from);
|
||||||
break;
|
break;
|
||||||
@ -3205,6 +3246,12 @@ copyObject(void *from)
|
|||||||
case T_CreateOpClassItem:
|
case T_CreateOpClassItem:
|
||||||
retval = _copyCreateOpClassItem(from);
|
retval = _copyCreateOpClassItem(from);
|
||||||
break;
|
break;
|
||||||
|
case T_CreateOpFamilyStmt:
|
||||||
|
retval = _copyCreateOpFamilyStmt(from);
|
||||||
|
break;
|
||||||
|
case T_AlterOpFamilyStmt:
|
||||||
|
retval = _copyAlterOpFamilyStmt(from);
|
||||||
|
break;
|
||||||
case T_CreatedbStmt:
|
case T_CreatedbStmt:
|
||||||
retval = _copyCreatedbStmt(from);
|
retval = _copyCreatedbStmt(from);
|
||||||
break;
|
break;
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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;
|
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
|
static bool
|
||||||
_equalRenameStmt(RenameStmt *a, RenameStmt *b)
|
_equalRenameStmt(RenameStmt *a, RenameStmt *b)
|
||||||
{
|
{
|
||||||
@ -1199,11 +1210,32 @@ _equalCreateOpClassItem(CreateOpClassItem *a, CreateOpClassItem *b)
|
|||||||
COMPARE_NODE_FIELD(args);
|
COMPARE_NODE_FIELD(args);
|
||||||
COMPARE_SCALAR_FIELD(number);
|
COMPARE_SCALAR_FIELD(number);
|
||||||
COMPARE_SCALAR_FIELD(recheck);
|
COMPARE_SCALAR_FIELD(recheck);
|
||||||
|
COMPARE_NODE_FIELD(class_args);
|
||||||
COMPARE_NODE_FIELD(storedtype);
|
COMPARE_NODE_FIELD(storedtype);
|
||||||
|
|
||||||
return true;
|
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
|
static bool
|
||||||
_equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
|
_equalCreatedbStmt(CreatedbStmt *a, CreatedbStmt *b)
|
||||||
{
|
{
|
||||||
@ -2148,6 +2180,9 @@ equal(void *a, void *b)
|
|||||||
case T_RemoveOpClassStmt:
|
case T_RemoveOpClassStmt:
|
||||||
retval = _equalRemoveOpClassStmt(a, b);
|
retval = _equalRemoveOpClassStmt(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_RemoveOpFamilyStmt:
|
||||||
|
retval = _equalRemoveOpFamilyStmt(a, b);
|
||||||
|
break;
|
||||||
case T_RenameStmt:
|
case T_RenameStmt:
|
||||||
retval = _equalRenameStmt(a, b);
|
retval = _equalRenameStmt(a, b);
|
||||||
break;
|
break;
|
||||||
@ -2190,6 +2225,12 @@ equal(void *a, void *b)
|
|||||||
case T_CreateOpClassItem:
|
case T_CreateOpClassItem:
|
||||||
retval = _equalCreateOpClassItem(a, b);
|
retval = _equalCreateOpClassItem(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_CreateOpFamilyStmt:
|
||||||
|
retval = _equalCreateOpFamilyStmt(a, b);
|
||||||
|
break;
|
||||||
|
case T_AlterOpFamilyStmt:
|
||||||
|
retval = _equalAlterOpFamilyStmt(a, b);
|
||||||
|
break;
|
||||||
case T_CreatedbStmt:
|
case T_CreatedbStmt:
|
||||||
retval = _equalCreatedbStmt(a, b);
|
retval = _equalCreatedbStmt(a, b);
|
||||||
break;
|
break;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.575 2007/01/22 01:35:21 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.576 2007/01/23 05:07:17 tgl Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -152,11 +152,12 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
AlterUserStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt
|
AlterUserStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt
|
||||||
AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
|
AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
|
||||||
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
|
ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
|
||||||
CreateDomainStmt CreateGroupStmt CreateOpClassStmt CreatePLangStmt
|
CreateDomainStmt CreateGroupStmt CreateOpClassStmt
|
||||||
|
CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
|
||||||
CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
|
CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
|
||||||
CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
|
CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
|
||||||
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
|
CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt
|
||||||
DropGroupStmt DropOpClassStmt DropPLangStmt DropStmt
|
DropGroupStmt DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt
|
||||||
DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
|
DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
|
||||||
DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
|
DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
|
||||||
GrantStmt GrantRoleStmt IndexStmt InsertStmt ListenStmt LoadStmt
|
GrantStmt GrantRoleStmt IndexStmt InsertStmt ListenStmt LoadStmt
|
||||||
@ -174,7 +175,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
%type <node> select_no_parens select_with_parens select_clause
|
%type <node> select_no_parens select_with_parens select_clause
|
||||||
simple_select values_clause
|
simple_select values_clause
|
||||||
|
|
||||||
%type <node> alter_column_default opclass_item alter_using
|
%type <node> alter_column_default opclass_item opclass_drop alter_using
|
||||||
%type <ival> add_drop opt_asc_desc opt_nulls_order
|
%type <ival> add_drop opt_asc_desc opt_nulls_order
|
||||||
|
|
||||||
%type <node> alter_table_cmd alter_rel_cmd
|
%type <node> alter_table_cmd alter_rel_cmd
|
||||||
@ -229,7 +230,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
OptTableElementList TableElementList OptInherit definition
|
OptTableElementList TableElementList OptInherit definition
|
||||||
OptWith opt_distinct opt_definition func_args func_args_list
|
OptWith opt_distinct opt_definition func_args func_args_list
|
||||||
func_as createfunc_opt_list alterfunc_opt_list
|
func_as createfunc_opt_list alterfunc_opt_list
|
||||||
aggr_args aggr_args_list old_aggr_definition old_aggr_list
|
aggr_args old_aggr_definition old_aggr_list
|
||||||
oper_argtypes RuleActionList RuleActionMulti
|
oper_argtypes RuleActionList RuleActionMulti
|
||||||
opt_column_list columnList opt_name_list
|
opt_column_list columnList opt_name_list
|
||||||
sort_clause opt_sort_clause sortby_list index_params
|
sort_clause opt_sort_clause sortby_list index_params
|
||||||
@ -240,10 +241,10 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
set_clause_list set_clause multiple_set_clause
|
set_clause_list set_clause multiple_set_clause
|
||||||
ctext_expr_list ctext_row def_list indirection opt_indirection
|
ctext_expr_list ctext_row def_list indirection opt_indirection
|
||||||
group_clause TriggerFuncArgs select_limit
|
group_clause TriggerFuncArgs select_limit
|
||||||
opt_select_limit opclass_item_list
|
opt_select_limit opclass_item_list opclass_drop_list
|
||||||
transaction_mode_list_or_empty
|
opt_opfamily transaction_mode_list_or_empty
|
||||||
TableFuncElementList opt_type_modifiers
|
TableFuncElementList opt_type_modifiers
|
||||||
prep_type_clause prep_type_list
|
prep_type_clause
|
||||||
execute_param_clause using_clause returning_clause
|
execute_param_clause using_clause returning_clause
|
||||||
|
|
||||||
%type <range> into_clause OptTempTableName
|
%type <range> into_clause OptTempTableName
|
||||||
@ -381,7 +382,7 @@ static Node *makeXmlExpr(XmlExprOp op, char *name, List *named_args, List *args)
|
|||||||
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
|
EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUDING
|
||||||
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
|
EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
|
||||||
|
|
||||||
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
|
FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD
|
||||||
FREEZE FROM FULL FUNCTION
|
FREEZE FROM FULL FUNCTION
|
||||||
|
|
||||||
GLOBAL GRANT GRANTED GREATEST GROUP_P
|
GLOBAL GRANT GRANTED GREATEST GROUP_P
|
||||||
@ -548,6 +549,8 @@ stmt :
|
|||||||
| CreateFunctionStmt
|
| CreateFunctionStmt
|
||||||
| CreateGroupStmt
|
| CreateGroupStmt
|
||||||
| CreateOpClassStmt
|
| CreateOpClassStmt
|
||||||
|
| CreateOpFamilyStmt
|
||||||
|
| AlterOpFamilyStmt
|
||||||
| CreatePLangStmt
|
| CreatePLangStmt
|
||||||
| CreateSchemaStmt
|
| CreateSchemaStmt
|
||||||
| CreateSeqStmt
|
| CreateSeqStmt
|
||||||
@ -565,6 +568,7 @@ stmt :
|
|||||||
| DropCastStmt
|
| DropCastStmt
|
||||||
| DropGroupStmt
|
| DropGroupStmt
|
||||||
| DropOpClassStmt
|
| DropOpClassStmt
|
||||||
|
| DropOpFamilyStmt
|
||||||
| DropOwnedStmt
|
| DropOwnedStmt
|
||||||
| DropPLangStmt
|
| DropPLangStmt
|
||||||
| DropRuleStmt
|
| DropRuleStmt
|
||||||
@ -2879,15 +2883,10 @@ def_arg: func_type { $$ = (Node *)$1; }
|
|||||||
| Sconst { $$ = (Node *)makeString($1); }
|
| Sconst { $$ = (Node *)makeString($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
aggr_args: '(' aggr_args_list ')' { $$ = $2; }
|
aggr_args: '(' type_list ')' { $$ = $2; }
|
||||||
| '(' '*' ')' { $$ = NIL; }
|
| '(' '*' ')' { $$ = NIL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
aggr_args_list:
|
|
||||||
Typename { $$ = list_make1($1); }
|
|
||||||
| aggr_args_list ',' Typename { $$ = lappend($1, $3); }
|
|
||||||
;
|
|
||||||
|
|
||||||
old_aggr_definition: '(' old_aggr_list ')' { $$ = $2; }
|
old_aggr_definition: '(' old_aggr_list ')' { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -2906,20 +2905,24 @@ old_aggr_elem: IDENT '=' def_arg
|
|||||||
*
|
*
|
||||||
* QUERIES :
|
* QUERIES :
|
||||||
* CREATE OPERATOR CLASS ...
|
* CREATE OPERATOR CLASS ...
|
||||||
|
* CREATE OPERATOR FAMILY ...
|
||||||
|
* ALTER OPERATOR FAMILY ...
|
||||||
* DROP OPERATOR CLASS ...
|
* DROP OPERATOR CLASS ...
|
||||||
|
* DROP OPERATOR FAMILY ...
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
CreateOpClassStmt:
|
CreateOpClassStmt:
|
||||||
CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
|
CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
|
||||||
USING access_method AS opclass_item_list
|
USING access_method opt_opfamily AS opclass_item_list
|
||||||
{
|
{
|
||||||
CreateOpClassStmt *n = makeNode(CreateOpClassStmt);
|
CreateOpClassStmt *n = makeNode(CreateOpClassStmt);
|
||||||
n->opclassname = $4;
|
n->opclassname = $4;
|
||||||
n->isDefault = $5;
|
n->isDefault = $5;
|
||||||
n->datatype = $8;
|
n->datatype = $8;
|
||||||
n->amname = $10;
|
n->amname = $10;
|
||||||
n->items = $12;
|
n->opfamilyname = $11;
|
||||||
|
n->items = $13;
|
||||||
$$ = (Node *) n;
|
$$ = (Node *) n;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -2959,6 +2962,16 @@ opclass_item:
|
|||||||
n->number = $2;
|
n->number = $2;
|
||||||
$$ = (Node *) n;
|
$$ = (Node *) n;
|
||||||
}
|
}
|
||||||
|
| FUNCTION Iconst '(' type_list ')' func_name func_args
|
||||||
|
{
|
||||||
|
CreateOpClassItem *n = makeNode(CreateOpClassItem);
|
||||||
|
n->itemtype = OPCLASS_ITEM_FUNCTION;
|
||||||
|
n->name = $6;
|
||||||
|
n->args = extractArgTypes($7);
|
||||||
|
n->number = $2;
|
||||||
|
n->class_args = $4;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
| STORAGE Typename
|
| STORAGE Typename
|
||||||
{
|
{
|
||||||
CreateOpClassItem *n = makeNode(CreateOpClassItem);
|
CreateOpClassItem *n = makeNode(CreateOpClassItem);
|
||||||
@ -2972,11 +2985,71 @@ opt_default: DEFAULT { $$ = TRUE; }
|
|||||||
| /*EMPTY*/ { $$ = FALSE; }
|
| /*EMPTY*/ { $$ = FALSE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
opt_opfamily: FAMILY any_name { $$ = $2; }
|
||||||
|
| /*EMPTY*/ { $$ = NIL; }
|
||||||
|
;
|
||||||
|
|
||||||
opt_recheck: RECHECK { $$ = TRUE; }
|
opt_recheck: RECHECK { $$ = TRUE; }
|
||||||
| /*EMPTY*/ { $$ = FALSE; }
|
| /*EMPTY*/ { $$ = FALSE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
CreateOpFamilyStmt:
|
||||||
|
CREATE OPERATOR FAMILY any_name USING access_method
|
||||||
|
{
|
||||||
|
CreateOpFamilyStmt *n = makeNode(CreateOpFamilyStmt);
|
||||||
|
n->opfamilyname = $4;
|
||||||
|
n->amname = $6;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
AlterOpFamilyStmt:
|
||||||
|
ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list
|
||||||
|
{
|
||||||
|
AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
|
||||||
|
n->opfamilyname = $4;
|
||||||
|
n->amname = $6;
|
||||||
|
n->isDrop = false;
|
||||||
|
n->items = $8;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
| ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list
|
||||||
|
{
|
||||||
|
AlterOpFamilyStmt *n = makeNode(AlterOpFamilyStmt);
|
||||||
|
n->opfamilyname = $4;
|
||||||
|
n->amname = $6;
|
||||||
|
n->isDrop = true;
|
||||||
|
n->items = $8;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
opclass_drop_list:
|
||||||
|
opclass_drop { $$ = list_make1($1); }
|
||||||
|
| opclass_drop_list ',' opclass_drop { $$ = lappend($1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
opclass_drop:
|
||||||
|
OPERATOR Iconst '(' type_list ')'
|
||||||
|
{
|
||||||
|
CreateOpClassItem *n = makeNode(CreateOpClassItem);
|
||||||
|
n->itemtype = OPCLASS_ITEM_OPERATOR;
|
||||||
|
n->number = $2;
|
||||||
|
n->args = $4;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
| FUNCTION Iconst '(' type_list ')'
|
||||||
|
{
|
||||||
|
CreateOpClassItem *n = makeNode(CreateOpClassItem);
|
||||||
|
n->itemtype = OPCLASS_ITEM_FUNCTION;
|
||||||
|
n->number = $2;
|
||||||
|
n->args = $4;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
DropOpClassStmt:
|
DropOpClassStmt:
|
||||||
DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
|
DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
|
||||||
{
|
{
|
||||||
@ -2998,6 +3071,28 @@ DropOpClassStmt:
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
DropOpFamilyStmt:
|
||||||
|
DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
|
||||||
|
{
|
||||||
|
RemoveOpFamilyStmt *n = makeNode(RemoveOpFamilyStmt);
|
||||||
|
n->opfamilyname = $4;
|
||||||
|
n->amname = $6;
|
||||||
|
n->behavior = $7;
|
||||||
|
n->missing_ok = false;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
| DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
|
||||||
|
{
|
||||||
|
RemoveOpFamilyStmt *n = makeNode(RemoveOpFamilyStmt);
|
||||||
|
n->opfamilyname = $6;
|
||||||
|
n->amname = $8;
|
||||||
|
n->behavior = $9;
|
||||||
|
n->missing_ok = true;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* QUERY:
|
* QUERY:
|
||||||
@ -3201,6 +3296,15 @@ CommentStmt:
|
|||||||
n->comment = $9;
|
n->comment = $9;
|
||||||
$$ = (Node *) n;
|
$$ = (Node *) n;
|
||||||
}
|
}
|
||||||
|
| COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text
|
||||||
|
{
|
||||||
|
CommentStmt *n = makeNode(CommentStmt);
|
||||||
|
n->objtype = OBJECT_OPFAMILY;
|
||||||
|
n->objname = $5;
|
||||||
|
n->objargs = list_make1(makeString($7));
|
||||||
|
n->comment = $9;
|
||||||
|
$$ = (Node *) n;
|
||||||
|
}
|
||||||
| COMMENT ON LARGE_P OBJECT_P NumericOnly IS comment_text
|
| COMMENT ON LARGE_P OBJECT_P NumericOnly IS comment_text
|
||||||
{
|
{
|
||||||
CommentStmt *n = makeNode(CommentStmt);
|
CommentStmt *n = makeNode(CommentStmt);
|
||||||
@ -4174,8 +4278,8 @@ DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_beha
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
opt_if_exists: IF_P EXISTS { $$ = true; }
|
opt_if_exists: IF_P EXISTS { $$ = TRUE; }
|
||||||
| /*EMPTY*/ { $$ = false; }
|
| /*EMPTY*/ { $$ = FALSE; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
@ -4294,6 +4398,15 @@ RenameStmt: ALTER AGGREGATE func_name aggr_args RENAME TO name
|
|||||||
n->newname = $9;
|
n->newname = $9;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
|
| ALTER OPERATOR FAMILY any_name USING access_method RENAME TO name
|
||||||
|
{
|
||||||
|
RenameStmt *n = makeNode(RenameStmt);
|
||||||
|
n->renameType = OBJECT_OPFAMILY;
|
||||||
|
n->object = $4;
|
||||||
|
n->subname = $6;
|
||||||
|
n->newname = $9;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
| ALTER SCHEMA name RENAME TO name
|
| ALTER SCHEMA name RENAME TO name
|
||||||
{
|
{
|
||||||
RenameStmt *n = makeNode(RenameStmt);
|
RenameStmt *n = makeNode(RenameStmt);
|
||||||
@ -4493,6 +4606,15 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
|
|||||||
n->newowner = $9;
|
n->newowner = $9;
|
||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
|
| ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleId
|
||||||
|
{
|
||||||
|
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||||
|
n->objectType = OBJECT_OPFAMILY;
|
||||||
|
n->object = $4;
|
||||||
|
n->addname = $6;
|
||||||
|
n->newowner = $9;
|
||||||
|
$$ = (Node *)n;
|
||||||
|
}
|
||||||
| ALTER SCHEMA name OWNER TO RoleId
|
| ALTER SCHEMA name OWNER TO RoleId
|
||||||
{
|
{
|
||||||
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
AlterOwnerStmt *n = makeNode(AlterOwnerStmt);
|
||||||
@ -5302,15 +5424,10 @@ PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
prep_type_clause: '(' prep_type_list ')' { $$ = $2; }
|
prep_type_clause: '(' type_list ')' { $$ = $2; }
|
||||||
| /* EMPTY */ { $$ = NIL; }
|
| /* EMPTY */ { $$ = NIL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
prep_type_list: Typename { $$ = list_make1($1); }
|
|
||||||
| prep_type_list ',' Typename
|
|
||||||
{ $$ = lappend($1, $3); }
|
|
||||||
;
|
|
||||||
|
|
||||||
PreparableStmt:
|
PreparableStmt:
|
||||||
SelectStmt
|
SelectStmt
|
||||||
| InsertStmt
|
| InsertStmt
|
||||||
@ -7968,14 +8085,8 @@ extract_list:
|
|||||||
| /*EMPTY*/ { $$ = NIL; }
|
| /*EMPTY*/ { $$ = NIL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
type_list: type_list ',' Typename
|
type_list: Typename { $$ = list_make1($1); }
|
||||||
{
|
| type_list ',' Typename { $$ = lappend($1, $3); }
|
||||||
$$ = lappend($1, $3);
|
|
||||||
}
|
|
||||||
| Typename
|
|
||||||
{
|
|
||||||
$$ = list_make1($1);
|
|
||||||
}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
array_expr_list: array_expr
|
array_expr_list: array_expr
|
||||||
@ -8604,6 +8715,7 @@ unreserved_keyword:
|
|||||||
| EXECUTE
|
| EXECUTE
|
||||||
| EXPLAIN
|
| EXPLAIN
|
||||||
| EXTERNAL
|
| EXTERNAL
|
||||||
|
| FAMILY
|
||||||
| FETCH
|
| FETCH
|
||||||
| FIRST_P
|
| FIRST_P
|
||||||
| FORCE
|
| FORCE
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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},
|
{"external", EXTERNAL},
|
||||||
{"extract", EXTRACT},
|
{"extract", EXTRACT},
|
||||||
{"false", FALSE_P},
|
{"false", FALSE_P},
|
||||||
|
{"family", FAMILY},
|
||||||
{"fetch", FETCH},
|
{"fetch", FETCH},
|
||||||
{"first", FIRST_P},
|
{"first", FIRST_P},
|
||||||
{"float", FLOAT_P},
|
{"float", FLOAT_P},
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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_IndexStmt:
|
||||||
case T_CreatePLangStmt:
|
case T_CreatePLangStmt:
|
||||||
case T_CreateOpClassStmt:
|
case T_CreateOpClassStmt:
|
||||||
|
case T_CreateOpFamilyStmt:
|
||||||
|
case T_AlterOpFamilyStmt:
|
||||||
case T_RuleStmt:
|
case T_RuleStmt:
|
||||||
case T_CreateSchemaStmt:
|
case T_CreateSchemaStmt:
|
||||||
case T_CreateSeqStmt:
|
case T_CreateSeqStmt:
|
||||||
@ -338,6 +340,7 @@ check_xact_readonly(Node *parsetree)
|
|||||||
case T_DropRoleStmt:
|
case T_DropRoleStmt:
|
||||||
case T_DropPLangStmt:
|
case T_DropPLangStmt:
|
||||||
case T_RemoveOpClassStmt:
|
case T_RemoveOpClassStmt:
|
||||||
|
case T_RemoveOpFamilyStmt:
|
||||||
case T_DropPropertyStmt:
|
case T_DropPropertyStmt:
|
||||||
case T_GrantStmt:
|
case T_GrantStmt:
|
||||||
case T_GrantRoleStmt:
|
case T_GrantRoleStmt:
|
||||||
@ -1099,10 +1102,22 @@ ProcessUtility(Node *parsetree,
|
|||||||
DefineOpClass((CreateOpClassStmt *) parsetree);
|
DefineOpClass((CreateOpClassStmt *) parsetree);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_CreateOpFamilyStmt:
|
||||||
|
DefineOpFamily((CreateOpFamilyStmt *) parsetree);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_AlterOpFamilyStmt:
|
||||||
|
AlterOpFamily((AlterOpFamilyStmt *) parsetree);
|
||||||
|
break;
|
||||||
|
|
||||||
case T_RemoveOpClassStmt:
|
case T_RemoveOpClassStmt:
|
||||||
RemoveOpClass((RemoveOpClassStmt *) parsetree);
|
RemoveOpClass((RemoveOpClassStmt *) parsetree);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_RemoveOpFamilyStmt:
|
||||||
|
RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "unrecognized node type: %d",
|
elog(ERROR, "unrecognized node type: %d",
|
||||||
(int) nodeTag(parsetree));
|
(int) nodeTag(parsetree));
|
||||||
@ -1445,6 +1460,9 @@ CreateCommandTag(Node *parsetree)
|
|||||||
case OBJECT_OPCLASS:
|
case OBJECT_OPCLASS:
|
||||||
tag = "ALTER OPERATOR CLASS";
|
tag = "ALTER OPERATOR CLASS";
|
||||||
break;
|
break;
|
||||||
|
case OBJECT_OPFAMILY:
|
||||||
|
tag = "ALTER OPERATOR FAMILY";
|
||||||
|
break;
|
||||||
case OBJECT_ROLE:
|
case OBJECT_ROLE:
|
||||||
tag = "ALTER ROLE";
|
tag = "ALTER ROLE";
|
||||||
break;
|
break;
|
||||||
@ -1518,6 +1536,9 @@ CreateCommandTag(Node *parsetree)
|
|||||||
case OBJECT_OPCLASS:
|
case OBJECT_OPCLASS:
|
||||||
tag = "ALTER OPERATOR CLASS";
|
tag = "ALTER OPERATOR CLASS";
|
||||||
break;
|
break;
|
||||||
|
case OBJECT_OPFAMILY:
|
||||||
|
tag = "ALTER OPERATOR FAMILY";
|
||||||
|
break;
|
||||||
case OBJECT_SCHEMA:
|
case OBJECT_SCHEMA:
|
||||||
tag = "ALTER SCHEMA";
|
tag = "ALTER SCHEMA";
|
||||||
break;
|
break;
|
||||||
@ -1777,10 +1798,22 @@ CreateCommandTag(Node *parsetree)
|
|||||||
tag = "CREATE OPERATOR CLASS";
|
tag = "CREATE OPERATOR CLASS";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_CreateOpFamilyStmt:
|
||||||
|
tag = "CREATE OPERATOR FAMILY";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_AlterOpFamilyStmt:
|
||||||
|
tag = "ALTER OPERATOR FAMILY";
|
||||||
|
break;
|
||||||
|
|
||||||
case T_RemoveOpClassStmt:
|
case T_RemoveOpClassStmt:
|
||||||
tag = "DROP OPERATOR CLASS";
|
tag = "DROP OPERATOR CLASS";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_RemoveOpFamilyStmt:
|
||||||
|
tag = "DROP OPERATOR FAMILY";
|
||||||
|
break;
|
||||||
|
|
||||||
case T_PrepareStmt:
|
case T_PrepareStmt:
|
||||||
tag = "PREPARE";
|
tag = "PREPARE";
|
||||||
break;
|
break;
|
||||||
@ -2147,10 +2180,22 @@ GetCommandLogLevel(Node *parsetree)
|
|||||||
lev = LOGSTMT_DDL;
|
lev = LOGSTMT_DDL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_CreateOpFamilyStmt:
|
||||||
|
lev = LOGSTMT_DDL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case T_AlterOpFamilyStmt:
|
||||||
|
lev = LOGSTMT_DDL;
|
||||||
|
break;
|
||||||
|
|
||||||
case T_RemoveOpClassStmt:
|
case T_RemoveOpClassStmt:
|
||||||
lev = LOGSTMT_DDL;
|
lev = LOGSTMT_DDL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case T_RemoveOpFamilyStmt:
|
||||||
|
lev = LOGSTMT_DDL;
|
||||||
|
break;
|
||||||
|
|
||||||
case T_PrepareStmt:
|
case T_PrepareStmt:
|
||||||
{
|
{
|
||||||
PrepareStmt *stmt = (PrepareStmt *) parsetree;
|
PrepareStmt *stmt = (PrepareStmt *) parsetree;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 */
|
/* commands/opclasscmds.c */
|
||||||
extern void DefineOpClass(CreateOpClassStmt *stmt);
|
extern void DefineOpClass(CreateOpClassStmt *stmt);
|
||||||
|
extern void DefineOpFamily(CreateOpFamilyStmt *stmt);
|
||||||
|
extern void AlterOpFamily(AlterOpFamilyStmt *stmt);
|
||||||
extern void RemoveOpClass(RemoveOpClassStmt *stmt);
|
extern void RemoveOpClass(RemoveOpClassStmt *stmt);
|
||||||
|
extern void RemoveOpFamily(RemoveOpFamilyStmt *stmt);
|
||||||
extern void RemoveOpClassById(Oid opclassOid);
|
extern void RemoveOpClassById(Oid opclassOid);
|
||||||
extern void RemoveOpFamilyById(Oid opfamilyOid);
|
extern void RemoveOpFamilyById(Oid opfamilyOid);
|
||||||
extern void RemoveAmOpEntryById(Oid entryOid);
|
extern void RemoveAmOpEntryById(Oid entryOid);
|
||||||
extern void RemoveAmProcEntryById(Oid entryOid);
|
extern void RemoveAmProcEntryById(Oid entryOid);
|
||||||
extern void RenameOpClass(List *name, const char *access_method, const char *newname);
|
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 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 */
|
/* support routines in commands/define.c */
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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_CreateCastStmt,
|
||||||
T_DropCastStmt,
|
T_DropCastStmt,
|
||||||
T_CreateOpClassStmt,
|
T_CreateOpClassStmt,
|
||||||
|
T_CreateOpFamilyStmt,
|
||||||
|
T_AlterOpFamilyStmt,
|
||||||
T_RemoveOpClassStmt,
|
T_RemoveOpClassStmt,
|
||||||
|
T_RemoveOpFamilyStmt,
|
||||||
T_PrepareStmt,
|
T_PrepareStmt,
|
||||||
T_ExecuteStmt,
|
T_ExecuteStmt,
|
||||||
T_DeallocateStmt,
|
T_DeallocateStmt,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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_LARGEOBJECT,
|
||||||
OBJECT_OPCLASS,
|
OBJECT_OPCLASS,
|
||||||
OBJECT_OPERATOR,
|
OBJECT_OPERATOR,
|
||||||
|
OBJECT_OPFAMILY,
|
||||||
OBJECT_ROLE,
|
OBJECT_ROLE,
|
||||||
OBJECT_RULE,
|
OBJECT_RULE,
|
||||||
OBJECT_SCHEMA,
|
OBJECT_SCHEMA,
|
||||||
@ -1194,7 +1195,7 @@ typedef struct DropTableSpaceStmt
|
|||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
char *tablespacename;
|
char *tablespacename;
|
||||||
bool missing_ok; /* skip error if a missing? */
|
bool missing_ok; /* skip error if missing? */
|
||||||
} DropTableSpaceStmt;
|
} DropTableSpaceStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
@ -1362,10 +1363,35 @@ typedef struct CreateOpClassItem
|
|||||||
List *args; /* argument types */
|
List *args; /* argument types */
|
||||||
int number; /* strategy num or support proc num */
|
int number; /* strategy num or support proc num */
|
||||||
bool recheck; /* only used for operators */
|
bool recheck; /* only used for operators */
|
||||||
|
List *class_args; /* only used for functions */
|
||||||
/* fields used for a storagetype item: */
|
/* fields used for a storagetype item: */
|
||||||
TypeName *storedtype; /* datatype stored in index */
|
TypeName *storedtype; /* datatype stored in index */
|
||||||
} CreateOpClassItem;
|
} 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
|
* Drop Table|Sequence|View|Index|Type|Domain|Conversion|Schema Statement
|
||||||
* ----------------------
|
* ----------------------
|
||||||
@ -1395,7 +1421,7 @@ typedef struct DropPropertyStmt
|
|||||||
char *property; /* name of rule, trigger, etc */
|
char *property; /* name of rule, trigger, etc */
|
||||||
ObjectType removeType; /* OBJECT_RULE or OBJECT_TRIGGER */
|
ObjectType removeType; /* OBJECT_RULE or OBJECT_TRIGGER */
|
||||||
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
||||||
bool missing_ok; /* skip error if a missing? */
|
bool missing_ok; /* skip error if missing? */
|
||||||
} DropPropertyStmt;
|
} DropPropertyStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
@ -1546,7 +1572,7 @@ typedef struct RemoveFuncStmt
|
|||||||
List *name; /* qualified name of object to drop */
|
List *name; /* qualified name of object to drop */
|
||||||
List *args; /* types of the arguments */
|
List *args; /* types of the arguments */
|
||||||
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
||||||
bool missing_ok; /* skip error if a missing? */
|
bool missing_ok; /* skip error if missing? */
|
||||||
} RemoveFuncStmt;
|
} RemoveFuncStmt;
|
||||||
|
|
||||||
/* ----------------------
|
/* ----------------------
|
||||||
@ -1559,9 +1585,22 @@ typedef struct RemoveOpClassStmt
|
|||||||
List *opclassname; /* qualified name (list of Value strings) */
|
List *opclassname; /* qualified name (list of Value strings) */
|
||||||
char *amname; /* name of index AM opclass is for */
|
char *amname; /* name of index AM opclass is for */
|
||||||
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
DropBehavior behavior; /* RESTRICT or CASCADE behavior */
|
||||||
bool missing_ok; /* skip error if a missing? */
|
bool missing_ok; /* skip error if missing? */
|
||||||
} RemoveOpClassStmt;
|
} 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
|
* Alter Object Rename Statement
|
||||||
* ----------------------
|
* ----------------------
|
||||||
@ -1917,7 +1956,7 @@ typedef struct DropCastStmt
|
|||||||
TypeName *sourcetype;
|
TypeName *sourcetype;
|
||||||
TypeName *targettype;
|
TypeName *targettype;
|
||||||
DropBehavior behavior;
|
DropBehavior behavior;
|
||||||
bool missing_ok; /* skip error if a missing? */
|
bool missing_ok; /* skip error if missing? */
|
||||||
} DropCastStmt;
|
} DropCastStmt;
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* An ACL array is simply an array of AclItems, representing the union
|
* 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_LANGUAGE, /* pg_language */
|
||||||
ACL_KIND_NAMESPACE, /* pg_namespace */
|
ACL_KIND_NAMESPACE, /* pg_namespace */
|
||||||
ACL_KIND_OPCLASS, /* pg_opclass */
|
ACL_KIND_OPCLASS, /* pg_opclass */
|
||||||
|
ACL_KIND_OPFAMILY, /* pg_opfamily */
|
||||||
ACL_KIND_CONVERSION, /* pg_conversion */
|
ACL_KIND_CONVERSION, /* pg_conversion */
|
||||||
ACL_KIND_TABLESPACE, /* pg_tablespace */
|
ACL_KIND_TABLESPACE, /* pg_tablespace */
|
||||||
MAX_ACL_KIND /* MUST BE LAST */
|
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_namespace_ownercheck(Oid nsp_oid, Oid roleid);
|
||||||
extern bool pg_tablespace_ownercheck(Oid spc_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_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_database_ownercheck(Oid db_oid, Oid roleid);
|
||||||
extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
|
extern bool pg_conversion_ownercheck(Oid conv_oid, Oid roleid);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user