Here is my next take on binary operators for integers.
It implements the following operators for int2/int4/int8:

 ~ - not
 & - and
 ^ - xor
 | - or
 << - shift left
 >> - shift right

Notes:

* My original choice for xor was '#' because the '^' operator conflicts
  with power operator on floats but Tom Lane said:

> Well, you *could* use '^' since there's no definition of it for integer
> operands.  But that would mean that something like '4^2', which was
> formerly implicitly coerced to float and interpreted as floating
> power function, would suddenly mean something different.  Again a
> serious risk of silently breaking applications.  This doesn't apply to
> '|' though, since it has no numeric interpretation at all right now.

  As the bit-string uses '^' too for xor-ing it would be nice to be
  consistent.  I am quite unsure on this matter.  The patch now seems
  otherwise sane to me, this is the only issue left.

* On << and >> the second argument is always int32 as this seems
  to be the 'default' int type in PostgreSQL.

* Oids used are 1874 - 1909.

Comments?

Patch is against current CVS.

-- 
marko
Mon, 25 Sep 2000 09:21:46 +0200
Marko Kreen <marko@l-t.ee>
binary operators on integers
Can someone comment on this?



> Here is my next take on binary operators for integers.
> It implements the following operators for int2/int4/int8:
> 
>  ~ - not
>  & - and
>  ^ - xor
>  | - or
>  << - shift left
>  >> - shift right
> 
> Notes:
> 
> * My original choice for xor was '#' because the '^' operator conflicts
>   with power operator on floats but Tom Lane said:
> 
> > Well, you *could* use '^' since there's no definition of it for integer
> > operands.  But that would mean that something like '4^2', which was
> > formerly implicitly coerced to float and interpreted as floating
> > power function, would suddenly mean something different.  Again a
> > serious risk of silently breaking applications.  This doesn't apply to
> > '|' though, since it has no numeric interpretation at all right now.
> 
>   As the bit-string uses '^' too for xor-ing it would be nice to be
>   consistent.  I am quite unsure on this matter.  The patch now seems
>   otherwise sane to me, this is the only issue left.
> 
> * On << and >> the second argument is always int32 as this seems
>   to be the 'default' int type in PostgreSQL.
> 
> * Oids used are 1874 - 1909.
> 
> Comments?
> 
> Patch is against current CVS.
> 
> -- 
> marko
> 

[ Attachment, skipping... ]


-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Tue, 17 Oct 2000 00:00:51 -0400 (EDT)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: binary operators on integers
Bruce Momjian <pgman@candle.pha.pa.us> writes:
> Can someone comment on this?

We were debating what to do about the precedence issues; see
followup messages.  I have no problem with adding functions
like this, just gotta pick the operator names and precedences...

			regards, tom lane

Tue, 17 Oct 2000 00:07:32 -0400
Tom Lane <tgl@sss.pgh.pa.us>
Re: binary operators on integers 
This patch was installed, with xor as "#".  The parser still needs work.  
Besides the known issue of "|", this also parses funny:

=> select 5 & ~ 6;
ERROR:  Unable to identify a right operator '&' for type 'int4'


Marko Kreen writes:

> Here is my next take on binary operators for integers.
> It implements the following operators for int2/int4/int8:
> 
>  ~ - not
>  & - and
>  ^ - xor
>  | - or
>  << - shift left
>  >> - shift right
> 
> Notes:
> 
> * My original choice for xor was '#' because the '^' operator conflicts
>   with power operator on floats but Tom Lane said:
> 
> > Well, you *could* use '^' since there's no definition of it for integer
> > operands.  But that would mean that something like '4^2', which was
> > formerly implicitly coerced to float and interpreted as floating
> > power function, would suddenly mean something different.  Again a
> > serious risk of silently breaking applications.  This doesn't apply to
> > '|' though, since it has no numeric interpretation at all right now.
> 
>   As the bit-string uses '^' too for xor-ing it would be nice to be
>   consistent.  I am quite unsure on this matter.  The patch now seems
>   otherwise sane to me, this is the only issue left.
> 
> * On << and >> the second argument is always int32 as this seems
>   to be the 'default' int type in PostgreSQL.
> 
> * Oids used are 1874 - 1909.
> 
> Comments?
> 
> Patch is against current CVS.
> 
> 

-- 
Peter Eisentraut      peter_e@gmx.net       http://yi.org/peter-e/


Tue, 24 Oct 2000 22:23:55 +0200 (CEST)
Peter Eisentraut <peter_e@gmx.net>
Re: binary operators on integers
On Tue, Oct 24, 2000 at 10:23:55PM +0200, Peter Eisentraut wrote:
> This patch was installed, with xor as "#".  The parser still needs work.  
> Besides the known issue of "|", this also parses funny:
> 
> => select 5 & ~ 6;
> ERROR:  Unable to identify a right operator '&' for type 'int4'

I have known that from the beginning.  On first patch I did not get
it work correctly, so in second patch I disabled all gram.y hack
altogether.  So this patch does not change anything in parser/.
At the moment it should be used:  select 5 & (~ 6);

I can hack the gram.y and scan.l to get those operators to work
but as I saw no consensus has been reached in -hackers whether
and how it should be solved globally?


-- 
marko


Tue, 24 Oct 2000 22:38:44 +0200
Marko Kreen <marko@l-t.ee>
Re: binary operators on integers
Peter Eisentraut <peter_e@gmx.net> writes:
> This patch was installed, with xor as "#".  The parser still needs work.  
> Besides the known issue of "|", this also parses funny:

> => select 5 & ~ 6;
> ERROR:  Unable to identify a right operator '&' for type 'int4'

I think we're kind of stuck on that, at least in terms of a solution
specifically for ~ --- I don't think we should be wiring knowledge of
whether specific operators are prefix/suffix/infix into the grammar.

It might perhaps be possible to tweak the grammar so that

	operand operator operator operand

is generically resolved as

	operand infix-op (prefix-op operand)

and not

	(operand postfix-op) infix-op operand

the way it is now.  Given that postfix operators are relatively seldom
used, this seems a more sensible default --- but I suppose somewhere out
there is an application that will break.  (At least it probably won't
break silently.)

Comments anyone?

			regards, tom lane

Tue, 24 Oct 2000 17:30:39 -0400
Tom Lane <tgl@sss.pgh.pa.us>
Re: [PATCHES] binary operators on integers 
Looks like this is fixed:
	
	test=> select 5 & ~ 6;
	ERROR:  Unable to identify a right operator '&' for type 'int4'
	        You may need to add parentheses or an explicit cast
	test=> select 5 & (~ 6);
	 ?column? 
	----------
	        1
	(1 row)

> This patch was installed, with xor as "#".  The parser still needs work.  
> Besides the known issue of "|", this also parses funny:
> 
> => select 5 & ~ 6;
> ERROR:  Unable to identify a right operator '&' for type 'int4'
> 
> 
> Marko Kreen writes:
> 
> > Here is my next take on binary operators for integers.
> > It implements the following operators for int2/int4/int8:
> > 
> >  ~ - not
> >  & - and
> >  ^ - xor
> >  | - or
> >  << - shift left
> >  >> - shift right
> > 
> > Notes:
> > 
> > * My original choice for xor was '#' because the '^' operator conflicts
> >   with power operator on floats but Tom Lane said:
> > 
> > > Well, you *could* use '^' since there's no definition of it for integer
> > > operands.  But that would mean that something like '4^2', which was
> > > formerly implicitly coerced to float and interpreted as floating
> > > power function, would suddenly mean something different.  Again a
> > > serious risk of silently breaking applications.  This doesn't apply to
> > > '|' though, since it has no numeric interpretation at all right now.
> > 
> >   As the bit-string uses '^' too for xor-ing it would be nice to be
> >   consistent.  I am quite unsure on this matter.  The patch now seems
> >   otherwise sane to me, this is the only issue left.
> > 
> > * On << and >> the second argument is always int32 as this seems
> >   to be the 'default' int type in PostgreSQL.
> > 
> > * Oids used are 1874 - 1909.
> > 
> > Comments?
> > 
> > Patch is against current CVS.
> > 
> > 
> 
> -- 
> Peter Eisentraut      peter_e@gmx.net       http://yi.org/peter-e/
> 
> 


-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Fri, 19 Jan 2001 16:30:09 -0500 (EST)
Bruce Momjian <pgman@candle.pha.pa.us>
Re: binary operators on integers
On Fri, Jan 19, 2001 at 04:30:09PM -0500, Bruce Momjian wrote:
> Looks like this is fixed:
> 	
> 	test=> select 5 & ~ 6;
> 	ERROR:  Unable to identify a right operator '&' for type 'int4'
> 	        You may need to add parentheses or an explicit cast
> 	test=> select 5 & (~ 6);
> 	 ?column? 
> 	----------
> 	        1
> 	(1 row)

I can still reproduce it:

marko=# SELECT 5 & ~6;
ERROR:  Unable to identify a right operator '&' for type 'int4'
        You may need to add parentheses or an explicit cast


Or did you mean it can be fixed with parenthesis?  That was the
case from the beginning.


> 
> > This patch was installed, with xor as "#".  The parser still needs work.  
> > Besides the known issue of "|", this also parses funny:
> > 
> > => select 5 & ~ 6;
> > ERROR:  Unable to identify a right operator '&' for type 'int4'
> > 

-- 
marko


Sat, 20 Jan 2001 17:31:28 +0200
Marko Kreen <marko@l-t.ee>
Re: binary operators on integers
Marko Kreen <marko@l-t.ee> writes:
> I can still reproduce it:
> marko=# SELECT 5 & ~6;
> ERROR:  Unable to identify a right operator '&' for type 'int4'
>         You may need to add parentheses or an explicit cast

Correct, we did not rejigger the operator precedence.

I played around with this a little bit, and find that the attached patch
makes the above case work as desired --- essentially, it changes things
so that
	a_expr Op Op a_expr
will be parsed as
	a_expr Op (Op a_expr)
not
	(a_expr Op) Op a_expr
which is what you get now because Op is marked left-associative.

Now, this is a situation where we can't fix one case without breaking
another, namely the case where you really DID want the first Op to be
parsed as a postfix operator.  Thus the problem moves over to here:

regression=# select 4! ~ 10;
ERROR:  Unable to identify an operator '!' for types 'int4' and 'int4'
        You will have to retype this query using an explicit cast
regression=# select (4!) ~ 10;
 ?column?
----------
 f
(1 row)

whereas this worked without parens in 7.0.

Given the infrequency of use of postfix operators compared to prefix,
I am inclined to think that we should change the grammar to make the
latter easier to use at the expense of the former.  On the other hand,
it seems there's a pretty large risk of backwards-incompatibility here.
Comments?

BTW, the regress tests do not break, so they contain no examples where
it makes a difference.

			regards, tom lane


*** src/backend/parser/gram.y.orig	Sat Jan 20 12:37:52 2001
--- src/backend/parser/gram.y	Sat Jan 20 13:03:17 2001
***************
*** 383,388 ****
--- 383,389 ----
  %nonassoc	OVERLAPS
  %nonassoc	BETWEEN
  %nonassoc	IN
+ %left		POSTFIXOP		/* dummy for postfix Op rules */
  %left		Op				/* multi-character ops and user-defined operators */
  %nonassoc	NOTNULL
  %nonassoc	ISNULL
***************
*** 4312,4320 ****
  				{	$$ = makeA_Expr(OP, "+", NULL, $2); }
  		| '-' a_expr					%prec UMINUS
  				{	$$ = doNegate($2); }
! 		| '%' a_expr
  				{	$$ = makeA_Expr(OP, "%", NULL, $2); }
! 		| '^' a_expr
  				{	$$ = makeA_Expr(OP, "^", NULL, $2); }
  		| a_expr '%'
  				{	$$ = makeA_Expr(OP, "%", $1, NULL); }
--- 4313,4321 ----
  				{	$$ = makeA_Expr(OP, "+", NULL, $2); }
  		| '-' a_expr					%prec UMINUS
  				{	$$ = doNegate($2); }
! 		| '%' a_expr					%prec UMINUS
  				{	$$ = makeA_Expr(OP, "%", NULL, $2); }
! 		| '^' a_expr					%prec UMINUS
  				{	$$ = makeA_Expr(OP, "^", NULL, $2); }
  		| a_expr '%'
  				{	$$ = makeA_Expr(OP, "%", $1, NULL); }
***************
*** 4353,4361 ****
  
  		| a_expr Op a_expr
  				{	$$ = makeA_Expr(OP, $2, $1, $3); }
! 		| Op a_expr
  				{	$$ = makeA_Expr(OP, $1, NULL, $2); }
! 		| a_expr Op
  				{	$$ = makeA_Expr(OP, $2, $1, NULL); }
  
  		| a_expr AND a_expr
--- 4354,4362 ----
  
  		| a_expr Op a_expr
  				{	$$ = makeA_Expr(OP, $2, $1, $3); }
! 		| Op a_expr					%prec UMINUS
  				{	$$ = makeA_Expr(OP, $1, NULL, $2); }
! 		| a_expr Op					%prec POSTFIXOP
  				{	$$ = makeA_Expr(OP, $2, $1, NULL); }
  
  		| a_expr AND a_expr
***************
*** 4560,4568 ****
  				{	$$ = makeA_Expr(OP, "+", NULL, $2); }
  		| '-' b_expr					%prec UMINUS
  				{	$$ = doNegate($2); }
! 		| '%' b_expr
  				{	$$ = makeA_Expr(OP, "%", NULL, $2); }
! 		| '^' b_expr
  				{	$$ = makeA_Expr(OP, "^", NULL, $2); }
  		| b_expr '%'
  				{	$$ = makeA_Expr(OP, "%", $1, NULL); }
--- 4561,4569 ----
  				{	$$ = makeA_Expr(OP, "+", NULL, $2); }
  		| '-' b_expr					%prec UMINUS
  				{	$$ = doNegate($2); }
! 		| '%' b_expr					%prec UMINUS
  				{	$$ = makeA_Expr(OP, "%", NULL, $2); }
! 		| '^' b_expr					%prec UMINUS
  				{	$$ = makeA_Expr(OP, "^", NULL, $2); }
  		| b_expr '%'
  				{	$$ = makeA_Expr(OP, "%", $1, NULL); }
***************
*** 4589,4597 ****
  
  		| b_expr Op b_expr
  				{	$$ = makeA_Expr(OP, $2, $1, $3); }
! 		| Op b_expr
  				{	$$ = makeA_Expr(OP, $1, NULL, $2); }
! 		| b_expr Op
  				{	$$ = makeA_Expr(OP, $2, $1, NULL); }
  		;
  
--- 4590,4598 ----
  
  		| b_expr Op b_expr
  				{	$$ = makeA_Expr(OP, $2, $1, $3); }
! 		| Op b_expr					%prec UMINUS
  				{	$$ = makeA_Expr(OP, $1, NULL, $2); }
! 		| b_expr Op					%prec POSTFIXOP
  				{	$$ = makeA_Expr(OP, $2, $1, NULL); }
  		;
  

Sat, 20 Jan 2001 13:31:49 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Re: [PATCHES] binary operators on integers 
On Sat, Jan 20, 2001 at 01:31:49PM -0500, Tom Lane wrote:
> Given the infrequency of use of postfix operators compared to prefix,
> I am inclined to think that we should change the grammar to make the
> latter easier to use at the expense of the former.  On the other hand,
> it seems there's a pretty large risk of backwards-incompatibility here.
> Comments?

I say, go for it! :) if it matters anything :]

And the backwards incompatibility should be simply mentioned in
release notes.  Only problem is, that this is such a obscure
incompatibility that I am not sure e.g. distro packagers bother
to mention it in new 7.1 install splash-screens.  "If you have
used factorial '!' or start of interval '|' operator in
expressions, note that ..." ?

-- 
marko


Sun, 21 Jan 2001 20:52:30 +0200
Marko Kreen <marko@l-t.ee>
Re: [PATCHES] binary operators on integers
I wrote:
> Given the infrequency of use of postfix operators compared to prefix,
> I am inclined to think that we should change the grammar to make the
> latter easier to use at the expense of the former.  On the other hand,
> it seems there's a pretty large risk of backwards-incompatibility here.
> Comments?

I backed away from part of the proposed patch --- changing the
precedence of all the prefix-operator productions to UMINUS would
probably break people's queries.  But I've applied the part that
changes the behavior of a_expr Op Op a_expr.  This will now be
parsed as an infix operator followed by a prefix operator.

			regards, tom lane

Tue, 23 Jan 2001 17:43:07 -0500
Tom Lane <tgl@sss.pgh.pa.us>
Re: [PATCHES] binary operators on integers 