Re: binary operators on integers - Mailing list pgsql-patches
From | Tom Lane |
---|---|
Subject | Re: binary operators on integers |
Date | |
Msg-id | 3670.980015509@sss.pgh.pa.us Whole thread Raw |
In response to | Re: binary operators on integers (Marko Kreen <marko@l-t.ee>) |
Responses |
Re: binary operators on integers
Re: binary operators on integers |
List | pgsql-patches |
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); } ;
pgsql-patches by date: