Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1ed6b89

Browse files
committed
Remove support for postfix (right-unary) operators.
This feature has been a thorn in our sides for a long time, causingmany grammatical ambiguity problems. It doesn't seem worth thepain to continue to support it, so remove it.There are some follow-on improvements we can make in the grammar,but this commit only removes the bare minimum number of productions,plus assorted backend support code.Note that pg_dump and psql continue to have full support, sincethey may be used against older servers. However, pg_dump warnsabout postfix operators. There is also a check in pg_upgrade.Documentation-wise, I (tgl) largely removed the "left unary"terminology in favor of saying "prefix operator", which isa more standard and IMO less confusing term.I included a catversion bump, although no initial catalog datachanges here, to mark the boundary at which oprkind = 'r'stopped being valid in pg_operator.Mark Dilger, based on work by myself and Robert Haas;review by John NaylorDiscussion:https://postgr.es/m/38ca86db-42ab-9b48-2902-337a0d6b8311@2ndquadrant.com
1 parent76f412a commit1ed6b89

32 files changed

+280
-340
lines changed

‎contrib/postgres_fdw/deparse.c

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,6 @@ deparseOpExpr(OpExpr *node, deparse_expr_cxt *context)
27062706
HeapTupletuple;
27072707
Form_pg_operatorform;
27082708
charoprkind;
2709-
ListCell*arg;
27102709

27112710
/* Retrieve information about the operator from system catalog. */
27122711
tuple=SearchSysCache1(OPEROID,ObjectIdGetDatum(node->opno));
@@ -2716,31 +2715,25 @@ deparseOpExpr(OpExpr *node, deparse_expr_cxt *context)
27162715
oprkind=form->oprkind;
27172716

27182717
/* Sanity check. */
2719-
Assert((oprkind=='r'&&list_length(node->args)==1)||
2720-
(oprkind=='l'&&list_length(node->args)==1)||
2718+
Assert((oprkind=='l'&&list_length(node->args)==1)||
27212719
(oprkind=='b'&&list_length(node->args)==2));
27222720

27232721
/* Always parenthesize the expression. */
27242722
appendStringInfoChar(buf,'(');
27252723

2726-
/* Deparse left operand. */
2727-
if (oprkind=='r'||oprkind=='b')
2724+
/* Deparse left operand, if any. */
2725+
if (oprkind=='b')
27282726
{
2729-
arg=list_head(node->args);
2730-
deparseExpr(lfirst(arg),context);
2727+
deparseExpr(linitial(node->args),context);
27312728
appendStringInfoChar(buf,' ');
27322729
}
27332730

27342731
/* Deparse operator name. */
27352732
deparseOperatorName(buf,form);
27362733

27372734
/* Deparse right operand. */
2738-
if (oprkind=='l'||oprkind=='b')
2739-
{
2740-
arg=list_tail(node->args);
2741-
appendStringInfoChar(buf,' ');
2742-
deparseExpr(lfirst(arg),context);
2743-
}
2735+
appendStringInfoChar(buf,' ');
2736+
deparseExpr(llast(node->args),context);
27442737

27452738
appendStringInfoChar(buf,')');
27462739

‎doc/src/sgml/catalogs.sgml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5159,8 +5159,8 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
51595159
<structfield>oprkind</structfield> <type>char</type>
51605160
</para>
51615161
<para>
5162-
<literal>b</literal> = infix (<quote>both</quote>), <literal>l</literal> = prefix
5163-
(<quote>left</quote>), <literal>r</literal> =postfix(<quote>right</quote>)
5162+
<literal>b</literal> = infixoperator(<quote>both</quote>),
5163+
or <literal>l</literal> =prefix operator(<quote>left</quote>)
51645164
</para></entry>
51655165
</row>
51665166

@@ -5188,7 +5188,7 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
51885188
(references <link linkend="catalog-pg-type"><structname>pg_type</structname></link>.<structfield>oid</structfield>)
51895189
</para>
51905190
<para>
5191-
Type of the left operand
5191+
Type of the left operand (0 if none)
51925192
</para></entry>
51935193
</row>
51945194

@@ -5266,7 +5266,7 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
52665266
</table>
52675267

52685268
<para>
5269-
Unusedcolumn contain zeroes. For example, <structfield>oprleft</structfield>
5269+
Unusedcolumns contain zeroes. For example, <structfield>oprleft</structfield>
52705270
is zero for a prefix operator.
52715271
</para>
52725272

‎doc/src/sgml/ref/alter_extension.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ ALTER EXTENSION <replaceable class="parameter">name</replaceable> DROP <replacea
251251
<para>
252252
The data type(s) of the operator's arguments (optionally
253253
schema-qualified). Write <literal>NONE</literal> for the missing argument
254-
of a prefixor postfixoperator.
254+
of a prefix operator.
255255
</para>
256256
</listitem>
257257
</varlistentry>

‎doc/src/sgml/ref/alter_operator.sgml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } ,{<replaceable>right_type</replaceable> | NONE } )
24+
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , <replaceable>right_type</replaceable> )
2525
OWNER TO { <replaceable>new_owner</replaceable> | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
2626

27-
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } ,{<replaceable>right_type</replaceable> | NONE } )
27+
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , <replaceable>right_type</replaceable> )
2828
SET SCHEMA <replaceable>new_schema</replaceable>
2929

30-
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } ,{<replaceable>right_type</replaceable> | NONE } )
30+
ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , <replaceable>right_type</replaceable> )
3131
SET ( { RESTRICT = { <replaceable class="parameter">res_proc</replaceable> | NONE }
3232
| JOIN = { <replaceable class="parameter">join_proc</replaceable> | NONE }
3333
} [, ... ] )
@@ -79,8 +79,7 @@ ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</repla
7979
<term><replaceable class="parameter">right_type</replaceable></term>
8080
<listitem>
8181
<para>
82-
The data type of the operator's right operand; write
83-
<literal>NONE</literal> if the operator has no right operand.
82+
The data type of the operator's right operand.
8483
</para>
8584
</listitem>
8685
</varlistentry>

‎doc/src/sgml/ref/alter_opfamily.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="
141141
<para>
142142
In an <literal>OPERATOR</literal> clause,
143143
the operand data type(s) of the operator, or <literal>NONE</literal> to
144-
signify aleft-unary or right-unary operator. Unlike the comparable
144+
signify aprefix operator. Unlike the comparable
145145
syntax in <command>CREATE OPERATOR CLASS</command>, the operand data types
146146
must always be specified.
147147
</para>

‎doc/src/sgml/ref/comment.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ COMMENT ON
224224
<para>
225225
The data type(s) of the operator's arguments (optionally
226226
schema-qualified). Write <literal>NONE</literal> for the missing argument
227-
of a prefixor postfixoperator.
227+
of a prefix operator.
228228
</para>
229229
</listitem>
230230
</varlistentry>

‎doc/src/sgml/ref/create_opclass.sgml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ CREATE OPERATOR CLASS <replaceable class="parameter">name</replaceable> [ DEFAUL
161161
<para>
162162
In an <literal>OPERATOR</literal> clause,
163163
the operand data type(s) of the operator, or <literal>NONE</literal> to
164-
signify aleft-unary or right-unary operator. The operand data
164+
signify aprefix operator. The operand data
165165
types can be omitted in the normal case where they are the same
166166
as the operator class's data type.
167167
</para>

‎doc/src/sgml/ref/create_operator.sgml

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -86,20 +86,9 @@ CREATE OPERATOR <replaceable>name</replaceable> (
8686
</para>
8787

8888
<para>
89-
At least one of <literal>LEFTARG</literal> and <literal>RIGHTARG</literal> must be defined. For
90-
binary operators, both must be defined. For right unary
91-
operators, only <literal>LEFTARG</literal> should be defined, while for left
92-
unary operators only <literal>RIGHTARG</literal> should be defined.
93-
</para>
94-
95-
<note>
96-
<para>
97-
Right unary, also called postfix, operators are deprecated and will be
98-
removed in <productname>PostgreSQL</productname> version 14.
99-
</para>
100-
</note>
101-
102-
<para>
89+
For binary operators, both <literal>LEFTARG</literal> and
90+
<literal>RIGHTARG</literal> must be defined. For prefix operators only
91+
<literal>RIGHTARG</literal> should be defined.
10392
The <replaceable class="parameter">function_name</replaceable>
10493
function must have been previously defined using <command>CREATE
10594
FUNCTION</command> and must be defined to accept the correct number
@@ -160,7 +149,7 @@ CREATE OPERATOR <replaceable>name</replaceable> (
160149
<listitem>
161150
<para>
162151
The data type of the operator's left operand, if any.
163-
This option would be omitted for aleft-unary operator.
152+
This option would be omitted for aprefix operator.
164153
</para>
165154
</listitem>
166155
</varlistentry>
@@ -169,8 +158,7 @@ CREATE OPERATOR <replaceable>name</replaceable> (
169158
<term><replaceable class="parameter">right_type</replaceable></term>
170159
<listitem>
171160
<para>
172-
The data type of the operator's right operand, if any.
173-
This option would be omitted for a right-unary operator.
161+
The data type of the operator's right operand.
174162
</para>
175163
</listitem>
176164
</varlistentry>

‎doc/src/sgml/ref/drop_operator.sgml

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
DROP OPERATOR [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ( { <replaceable class="parameter">left_type</replaceable> | NONE } ,{<replaceable class="parameter">right_type</replaceable> | NONE } ) [, ...] [ CASCADE | RESTRICT ]
24+
DROP OPERATOR [ IF EXISTS ] <replaceable class="parameter">name</replaceable> ( { <replaceable class="parameter">left_type</replaceable> | NONE } , <replaceable class="parameter">right_type</replaceable> ) [, ...] [ CASCADE | RESTRICT ]
2525
</synopsis>
2626
</refsynopsisdiv>
2727

@@ -73,8 +73,7 @@ DROP OPERATOR [ IF EXISTS ] <replaceable class="parameter">name</replaceable> (
7373
<term><replaceable class="parameter">right_type</replaceable></term>
7474
<listitem>
7575
<para>
76-
The data type of the operator's right operand; write
77-
<literal>NONE</literal> if the operator has no right operand.
76+
The data type of the operator's right operand.
7877
</para>
7978
</listitem>
8079
</varlistentry>
@@ -113,24 +112,17 @@ DROP OPERATOR ^ (integer, integer);
113112
</para>
114113

115114
<para>
116-
Remove theleft unarybitwisecomplement operator
115+
Remove the bitwise-complement prefix operator
117116
<literal>~b</literal> for type <type>bit</type>:
118117
<programlisting>
119118
DROP OPERATOR ~ (none, bit);
120119
</programlisting>
121120
</para>
122121

123-
<para>
124-
Remove the right unary factorial operator <literal>x!</literal>
125-
for type <type>bigint</type>:
126-
<programlisting>
127-
DROP OPERATOR ! (bigint, none);
128-
</programlisting></para>
129-
130122
<para>
131123
Remove multiple operators in one command:
132124
<programlisting>
133-
DROP OPERATOR ~ (none, bit),! (bigint, none);
125+
DROP OPERATOR ~ (none, bit),^ (integer, integer);
134126
</programlisting></para>
135127
</refsect1>
136128

‎doc/src/sgml/syntax.sgml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ CAST ( '<replaceable>string</replaceable>' AS <replaceable>type</replaceable> )
836836
<para>
837837
When working with non-SQL-standard operator names, you will usually
838838
need to separate adjacent operators with spaces to avoid ambiguity.
839-
For example, if you have defined aleft unary operator named <literal>@</literal>,
839+
For example, if you have defined aprefix operator named <literal>@</literal>,
840840
you cannot write <literal>X*@Y</literal>; you must write
841841
<literal>X* @Y</literal> to ensure that
842842
<productname>PostgreSQL</productname> reads it as two operator names
@@ -1444,11 +1444,10 @@ $1.somecolumn
14441444
</indexterm>
14451445

14461446
<para>
1447-
There arethree possible syntaxes for an operator invocation:
1447+
There aretwo possible syntaxes for an operator invocation:
14481448
<simplelist>
14491449
<member><replaceable>expression</replaceable> <replaceable>operator</replaceable> <replaceable>expression</replaceable> (binary infix operator)</member>
14501450
<member><replaceable>operator</replaceable> <replaceable>expression</replaceable> (unary prefix operator)</member>
1451-
<member><replaceable>expression</replaceable> <replaceable>operator</replaceable> (unary postfix operator)</member>
14521451
</simplelist>
14531452
where the <replaceable>operator</replaceable> token follows the syntax
14541453
rules of <xref linkend="sql-syntax-operators"/>, or is one of the

‎doc/src/sgml/typeconv.sgml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ Operators
9797
<listitem>
9898
<para>
9999
<productname>PostgreSQL</productname> allows expressions with
100-
prefixand postfix unary(one-argument) operators,
101-
as well asbinary (two-argument) operators. Like functions, operators can
100+
prefix (one-argument) operators,
101+
as well asinfix (two-argument) operators. Like functions, operators can
102102
be overloaded, so the same problem of selecting the right operator
103103
exists.
104104
</para>
@@ -266,7 +266,7 @@ create objects. In such situations, cast arguments to force an exact match.
266266
<para>
267267
If one argument of a binary operator invocation is of the <type>unknown</type> type,
268268
then assume it is the same type as the other argument for this check.
269-
Invocations involving two <type>unknown</type> inputs, or aunary operator
269+
Invocations involving two <type>unknown</type> inputs, or aprefix operator
270270
with an <type>unknown</type> input, will never find a match at this step.
271271
</para>
272272
</step>

‎doc/src/sgml/xoper.sgml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
</para>
2121

2222
<para>
23-
<productname>PostgreSQL</productname> supportsleft unary, right
24-
unary,andbinary operators. Operators can be
23+
<productname>PostgreSQL</productname> supportsprefix
24+
andinfix operators. Operators can be
2525
overloaded;<indexterm><primary>overloading</primary><secondary>operators</secondary></indexterm>
2626
that is, the same operator name can be used for different operators
2727
that have different numbers and types of operands. When a query is
@@ -64,9 +64,9 @@ SELECT (a + b) AS c FROM test_complex;
6464
</para>
6565

6666
<para>
67-
We've shown how to create a binary operator here. To createunary
68-
operators, just omitone of<literal>leftarg</literal> (for left unary) or
69-
<literal>rightarg</literal> (for right unary).The <literal>function</literal>
67+
We've shown how to create a binary operator here. To createa prefix
68+
operator, just omitthe<literal>leftarg</literal>.
69+
The <literal>function</literal>
7070
clause and the argument clauses are the only required items in
7171
<command>CREATE OPERATOR</command>. The <literal>commutator</literal>
7272
clause shown in the example is an optional hint to the query
@@ -202,7 +202,7 @@ SELECT (a + b) AS c FROM test_complex;
202202
<para>
203203
Unlike commutators, a pair of unary operators could validly be marked
204204
as each other's negators; that would mean (A x) equals NOT (B x)
205-
for all x, or the equivalent for right unary operators.
205+
for all x.
206206
</para>
207207

208208
<para>

‎src/backend/catalog/namespace.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,8 +1473,7 @@ FunctionIsVisible(Oid funcid)
14731473
*Given a possibly-qualified operator name and exact input datatypes,
14741474
*look up the operator. Returns InvalidOid if not found.
14751475
*
1476-
* Pass oprleft = InvalidOid for a prefix op, oprright = InvalidOid for
1477-
* a postfix op.
1476+
* Pass oprleft = InvalidOid for a prefix op.
14781477
*
14791478
* If the operator name is not schema-qualified, it is sought in the current
14801479
* namespace search path. If the name is schema-qualified and the given
@@ -1580,8 +1579,8 @@ OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
15801579
* namespace case, we arrange for entries in earlier namespaces to mask
15811580
* identical entries in later namespaces.
15821581
*
1583-
* The returned items always have two args[] entries ---one or the other
1584-
*will beInvalidOid for a prefixor postfixoprkind. nargs is 2, too.
1582+
* The returned items always have two args[] entries ---the first will be
1583+
* InvalidOid for a prefix oprkind. nargs is always 2, too.
15851584
*/
15861585
FuncCandidateList
15871586
OpernameGetCandidates(List*names,charoprkind,boolmissing_schema_ok)

‎src/backend/catalog/pg_operator.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ OperatorShellMake(const char *operatorName,
245245
values[Anum_pg_operator_oprname-1]=NameGetDatum(&oname);
246246
values[Anum_pg_operator_oprnamespace-1]=ObjectIdGetDatum(operatorNamespace);
247247
values[Anum_pg_operator_oprowner-1]=ObjectIdGetDatum(GetUserId());
248-
values[Anum_pg_operator_oprkind-1]=CharGetDatum(leftTypeId ?(rightTypeId ?'b' :'r') :'l');
248+
values[Anum_pg_operator_oprkind-1]=CharGetDatum(leftTypeId ?'b' :'l');
249249
values[Anum_pg_operator_oprcanmerge-1]=BoolGetDatum(false);
250250
values[Anum_pg_operator_oprcanhash-1]=BoolGetDatum(false);
251251
values[Anum_pg_operator_oprleft-1]=ObjectIdGetDatum(leftTypeId);
@@ -494,7 +494,7 @@ OperatorCreate(const char *operatorName,
494494
values[Anum_pg_operator_oprname-1]=NameGetDatum(&oname);
495495
values[Anum_pg_operator_oprnamespace-1]=ObjectIdGetDatum(operatorNamespace);
496496
values[Anum_pg_operator_oprowner-1]=ObjectIdGetDatum(GetUserId());
497-
values[Anum_pg_operator_oprkind-1]=CharGetDatum(leftTypeId ?(rightTypeId ?'b' :'r') :'l');
497+
values[Anum_pg_operator_oprkind-1]=CharGetDatum(leftTypeId ?'b' :'l');
498498
values[Anum_pg_operator_oprcanmerge-1]=BoolGetDatum(canMerge);
499499
values[Anum_pg_operator_oprcanhash-1]=BoolGetDatum(canHash);
500500
values[Anum_pg_operator_oprleft-1]=ObjectIdGetDatum(leftTypeId);

‎src/backend/commands/operatorcmds.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,10 +168,22 @@ DefineOperator(List *names, List *parameters)
168168
if (typeName2)
169169
typeId2=typenameTypeId(NULL,typeName2);
170170

171+
/*
172+
* If only the right argument is missing, the user is likely trying to
173+
* create a postfix operator, so give them a hint about why that does not
174+
* work. But if both arguments are missing, do not mention postfix
175+
* operators, as the user most likely simply neglected to mention the
176+
* arguments.
177+
*/
171178
if (!OidIsValid(typeId1)&& !OidIsValid(typeId2))
172179
ereport(ERROR,
173180
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
174-
errmsg("at least one of leftarg or rightarg must be specified")));
181+
errmsg("operator argument types must be specified")));
182+
if (!OidIsValid(typeId2))
183+
ereport(ERROR,
184+
(errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
185+
errmsg("operator right argument type must be specified"),
186+
errdetail("Postfix operators are not supported.")));
175187

176188
if (typeName1)
177189
{

‎src/backend/nodes/print.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ print_expr(const Node *expr, const List *rtable)
394394
}
395395
else
396396
{
397-
/* we print prefix and postfix ops the same... */
398397
printf("%s ", ((opname!=NULL) ?opname :"(invalid operator)"));
399398
print_expr(get_leftop((constExpr*)e),rtable);
400399
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp