Skip to content

Commit 1ed6b89

Browse files
committed
Remove support for postfix (right-unary) operators.
This feature has been a thorn in our sides for a long time, causing many grammatical ambiguity problems. It doesn't seem worth the pain 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, since they may be used against older servers. However, pg_dump warns about 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 is a more standard and IMO less confusing term. I included a catversion bump, although no initial catalog data changes 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 Naylor Discussion: https://postgr.es/m/[email protected]
1 parent 76f412a commit 1ed6b89

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
HeapTuple tuple;
27072707
Form_pg_operator form;
27082708
char oprkind;
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> = infix operator (<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-
Unused column contain zeroes. For example, <structfield>oprleft</structfield>
5269+
Unused columns 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 prefix or postfix operator.
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 a left-unary or right-unary operator. Unlike the comparable
144+
signify a prefix 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 prefix or postfix operator.
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 a left-unary or right-unary operator. The operand data
164+
signify a prefix 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 a left-unary operator.
152+
This option would be omitted for a prefix 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 the left unary bitwise complement 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 a left unary operator named <literal>@</literal>,
839+
For example, if you have defined a prefix 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 are three possible syntaxes for an operator invocation:
1447+
There are two 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

0 commit comments

Comments
 (0)