Re: Precedence of %

Lists: pgsql-hackers
From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: PostgreSQL-development <pgsql-hackers(at)postgreSQL(dot)org>
Subject: Precedence of %
Date: 2005-06-04 03:56:46
Message-ID: 200506040356.j543uki09397@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Does anyone understand why the precedence of % is strange:

test=> select -25 % -10;
?column?
----------
-35
(1 row)

test=> select -25 % (-10);
?column?
----------
-5
(1 row)

Is it treating the first as -25 - 10? Why? Why are parens necessary to
get the right answer? I see this in gram.y:

%left '+' '-'
%left '*' '/' '%'

Look at this:

test=> select -25 + -10;
?column?
----------
-35
(1 row)

test=> select -25 * -10;
?column?
----------
250
(1 row)

test=> select -25 / -10;
?column?
----------
2
(1 row)

test=> select -25 % -10;
?column?
----------
-35
(1 row)

Only the '%' case looks wrong.

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Precedence of %
Date: 2005-06-04 04:37:35
Message-ID: 23326.1117859855@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
> Does anyone understand why the precedence of % is strange:
> test=> select -25 % -10;

It's treating it as ((-25) %) - (10), which is probably not so
surprising given the relative precedence of % and - ... though
I have to admit I'm not totally clear why it's not (-(25 %)) - (10)
instead.

We could maybe hack the precedence of the productions for prefix/postfix
%, but I wonder if it wouldn't be smarter to remove 'em altogether
(along with the two existing unary % operators).

regards, tom lane


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Precedence of %
Date: 2005-06-04 15:31:18
Message-ID: 26635.1117899078@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

I wrote:
> Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us> writes:
>> Does anyone understand why the precedence of % is strange:
>> test=> select -25 % -10;

> It's treating it as ((-25) %) - (10), which is probably not so
> surprising given the relative precedence of % and - ... though
> I have to admit I'm not totally clear why it's not (-(25 %)) - (10)
> instead.

Now that I'm fully awake, that last point is easily explained: the
precedence of unary minus is higher than that of %, which in turn
is higher than that of infix minus. So the choice of (-25) % over
-(25 %) is reasonable and correct. Now when the parser is done with
that, it is on the % with a lookahead of - and has to decide whether
to reduce according to

| a_expr '%'
{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, NULL); }

or shift expecting to later reduce by

| a_expr '%' a_expr
{ $$ = (Node *) makeSimpleA_Expr(AEXPR_OP, "%", $1, $3); }

but the precedence of the '-' token is set up for infix minus so the
choice is to reduce (see the Bison manual).

We could possibly fix this by fooling with the precedence of the
productions for postfix '%', but I'm worried that that would have
unintended side-effects. What I'd like to propose instead is that
we remove prefix and postfix '%' entirely --- and also '^', which
is the only other hard-wired operator that appears in all three
forms in the grammar. There are no actual uses of prefix or postfix
'^' in pg_operator, so that loses us nothing. Prefix and postfix '%'
exist, but only for the float8 datatype, not anything else; and I
can't imagine a good reason to write those rather than trunc() or
round(). (Quick: which is which, and how would you remember?)

round() and trunc() also have the virtue that they already have versions
for type numeric. If we keep the operators then we'll be right back
with the complaint that was lodged the other day about exponentiation,
namely unexpected precision loss for numeric inputs:

regression=# select 12345678901234567890.55 %;
?column?
----------------------
1.23456789012346e+19
(1 row)

regression=# select round(12345678901234567890.55);
round
----------------------
12345678901234567891
(1 row)

Comments?

regards, tom lane


From: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Precedence of %
Date: 2005-06-04 15:38:05
Message-ID: 200506041538.j54Fc5d18589@candle.pha.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Tom Lane wrote:
> We could possibly fix this by fooling with the precedence of the
> productions for postfix '%', but I'm worried that that would have
> unintended side-effects. What I'd like to propose instead is that
> we remove prefix and postfix '%' entirely --- and also '^', which
> is the only other hard-wired operator that appears in all three
> forms in the grammar. There are no actual uses of prefix or postfix
> '^' in pg_operator, so that loses us nothing. Prefix and postfix '%'
> exist, but only for the float8 datatype, not anything else; and I
> can't imagine a good reason to write those rather than trunc() or
> round(). (Quick: which is which, and how would you remember?)

Agreed. I didn't know we even supported unary % and ~, and I doubt
anyone else did either. We just need to mark it as a non-backward
compatible change in CVS commit so I mention it in the release notes.

--
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073


From: Christopher Kings-Lynne <chriskl(at)familyhealth(dot)com(dot)au>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Precedence of %
Date: 2005-06-04 15:43:14
Message-ID: 42A1CC12.2040707@familyhealth.com.au
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

> round() and trunc() also have the virtue that they already have versions
> for type numeric. If we keep the operators then we'll be right back
> with the complaint that was lodged the other day about exponentiation,
> namely unexpected precision loss for numeric inputs:
>
> regression=# select 12345678901234567890.55 %;
> ?column?
> ----------------------
> 1.23456789012346e+19
> (1 row)

I don't even grasp what unary modulo actually means???

Chris


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Christopher Kings-Lynne <chriskl(at)familyhealth(dot)com(dot)au>
Cc: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Precedence of %
Date: 2005-06-04 15:55:37
Message-ID: 27481.1117900537@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Christopher Kings-Lynne <chriskl(at)familyhealth(dot)com(dot)au> writes:
> I don't even grasp what unary modulo actually means???

At some point in the dim mists of prehistory, somebody thought it would
be cute to define prefix % as trunc() and postfix % as round(). I'm not
aware of any precedent for that; it was probably mostly an exercise in
testing out the grammar.

Now that I look, it doesn't look like these operators are documented
at all in the SGML docs, so it sure seems that removing them should be
pretty painless.

regards, tom lane


From: Michael Glaesemann <grzm(at)myrealbox(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Precedence of %
Date: 2005-06-04 16:06:05
Message-ID: AC4B136B-0C3C-4D4D-AFE0-AFA62EA42FE3@myrealbox.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers


On Jun 5, 2005, at 12:55 AM, Tom Lane wrote:

> Now that I look, it doesn't look like these operators are documented
> at all in the SGML docs, so it sure seems that removing them should be
> pretty painless.

I wonder what else is lurking around undocumented and unused? Might
be some other nuggets just waiting to be discovered! :)

Michael Glaesemann
grzm myrealbox com


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Michael Glaesemann <grzm(at)myrealbox(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Precedence of %
Date: 2005-06-04 16:23:27
Message-ID: 2169.1117902207@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Michael Glaesemann <grzm(at)myrealbox(dot)com> writes:
> On Jun 5, 2005, at 12:55 AM, Tom Lane wrote:
>> Now that I look, it doesn't look like these operators are documented
>> at all in the SGML docs, so it sure seems that removing them should be
>> pretty painless.

> I wonder what else is lurking around undocumented and unused?

AFAIK, no one has ever gone through pg_proc and pg_operator
systematically to determine that every entry is either (a) documented
or (b) undocumented for definable reasons. We generally don't document
functions separately if they are accessible by a well-used operator;
for instance you're supposed to write "2+2" not "int4pl(2,2)". And
stuff that's supposed to be used only internally by the system, such
as index access method support functions, doesn't need to be listed.
But I wouldn't be at all surprised if some entries have just fallen
through the cracks. Anyone want to take on this bit of legwork?

regards, tom lane


From: Christopher Kings-Lynne <chriskl(at)familyhealth(dot)com(dot)au>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Bruce Momjian <pgman(at)candle(dot)pha(dot)pa(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Precedence of %
Date: 2005-06-05 03:53:41
Message-ID: 42A27745.9010701@familyhealth.com.au
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

> Now that I look, it doesn't look like these operators are documented
> at all in the SGML docs, so it sure seems that removing them should be
> pretty painless.

I'd agree with that....

Chris