Re: Unary Operators

From: Rowan Collins <rowan(dot)collins(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Unary Operators
Date: 2013-09-17 23:17:02
Message-ID: 5238E2EE.10703@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On 15/09/2013 19:32, Andreas Ulbrich wrote:
> Salvete!
>
> I have the following problem.
> I'd like to define the operator symbol / as a left unary operator for
> reciprocal value of a number.
> I did this with a C-function and all the stuff around, but it does not
> work.
> Hiere is an extract and simplified example with the same error message
> as in my complex example:
>
> create function reciproce(float) returns float as
> $$ values(1.0::float / $1) $$ language sql immutable strict;
> create operator / (rightarg = float, procedure = reciproce);
> select / 5.0::float;
> -->
> ERROR: syntax error at or near "/"
> LINE 1: select / 5.0;

Interesting that it's a syntax error. Defining it as // works fine, so
it's not the / symbol in general that's causing the problem, but
specifically a token consisting only of a single /, which presumably
(nearly) matches some particular rule in the parser.

The documentation page on Lexical Structure
(http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html)
doesn't specifically mention that this is reserved when it is describing
restrictions on custom operators. However, further down that page it
says "The precedence and associativity of the operators is hard-wired
into the parser." and "the operator precedence rules also apply to
user-defined operators that have the same names as the built-in
operators mentioned above". Note that + and - exist both as unary and
binary operators, but with different rules; any custom operators, on the
other hand, fall into a fairly low-precedence "any other" bucket.

My guess is that the "hard-wired" parsing rule for the (binary) /
operator is trying to match the / in your query, and failing to find its
left-hand argument. The "some other operator" rule, which would be able
to look for a unary operator, isn't even getting a chance. This is borne
out by looking at the other operators in that table - I've tried ^ and *
and get the same error (you need some extra brackets around "SELECT (*
5.0)" otherwise it would look like "SELECT *", which is an entirely
different piece of syntax!).

Someone who knows more about the internals may come along and tell me
I'm barking up completely the wrong tree, but it's at least a logical
explanation. If it is true, it should probably either be considered a
parser bug, or listed as a restriction on operator creation alongside --
and /* (or both).

Regards,
--
Rowan Collins
[IMSoP]

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Gurkan Ozfidan 2013-09-17 23:44:45 Cannot commit when autoCommit is enabled error
Previous Message Lonni J Friedman 2013-09-17 22:49:26 Re: upgrade from 9.2.x to 9.3 causes significant performance degradation