Well, I was interested in binary operators on integers
and as Peter suggested that I should look into it
myself, so I did it.

Choice of operators:

 ~ - not
 & - and
 # - xor  - I like it :)
 | - or

Things I am unsure of:

1) Precedence.  I quite nonscientifically hacked in gram.y,
   and could not still make it understand expression '5 # ~1'
   nor the precedence between '&' and '|#'...

   At the moment all the gram.y changes could be dropped and
   it works ok, but without operator precedence.  Any hints?

2) Choice of oids.  I took 1890 - 1913.  Should I have taken
   directly from 1874 upwards, or somewhere else?

3) Choice of operators.  As I understand the '^' is taken,
   I wont get it.  Now, in gram.y I found that the '|' is
   used in weird situations and with weird precedence so
   maybe I should use something else for OR too?

4) Is anybody else interested? ;)


I would like to get comments/further hints on this...



-- 
marko

Index: pgsql/doc/src/sgml/oper.sgml
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/doc/src/sgml/oper.sgml,v
retrieving revision 1.18
diff -u -r1.18 oper.sgml
--- pgsql/doc/src/sgml/oper.sgml        2000/09/15 20:20:11     1.18
+++ pgsql/doc/src/sgml/oper.sgml        2000/09/20 19:04:44
@@ -493,9 +493,35 @@
        <ENTRY>Cube root</ENTRY>
        <ENTRY>||/ 27.0</ENTRY>
        </ROW>
+       <ROW>
+       <ENTRY> & </ENTRY>
+       <ENTRY>Binary AND</ENTRY>
+       <ENTRY>91 & 15</ENTRY>
+       </ROW>
+       <ROW>
+       <ENTRY> | </ENTRY>
+       <ENTRY>Binary OR</ENTRY>
+       <ENTRY>32 | 3</ENTRY>
+       </ROW>
+       <ROW>
+       <ENTRY> # </ENTRY>
+       <ENTRY>Binary XOR</ENTRY>
+       <ENTRY>15 # 4</ENTRY>
+       </ROW>
+       <ROW>
+       <ENTRY> ~ </ENTRY>
+       <ENTRY>Binary NOT</ENTRY>
+       <ENTRY>~ 1</ENTRY>
+       </ROW>
       </TBODY>
      </TGROUP>
     </TABLE>
+    <Note>
+     <Para>
+     The binary operators work only on fixed-precision integer types,
+     that is, on the int2, int4 and int8.
+     </Para>
+    </Note>
    </Para>
   </sect1>
 
Index: pgsql/src/backend/parser/gram.y
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.191
diff -u -r2.191 gram.y
--- pgsql/src/backend/parser/gram.y     2000/09/19 18:17:55     2.191
+++ pgsql/src/backend/parser/gram.y     2000/09/20 19:04:57
@@ -374,10 +374,13 @@
 %nonassoc      ISNULL
 %nonassoc      NULL_P
 %nonassoc      IS
+%left          '|'
+%left          '#'
+%left          '&'
 %left          '+' '-'
 %left          '*' '/' '%'
 %left          '^'
-%left          '|'                             /* XXX Should this have such a high 
priority? */
+/* %left       '|' */                          /* marko - No: Should this have such a 
+high priority? */
 /* Unary Operators */
 %right         UMINUS
 %left          '.'
@@ -4423,6 +4426,9 @@
                | '/'                   { $$ = "/"; }
                | '%'                   { $$ = "%"; }
                | '^'                   { $$ = "^"; }
+               | '~'                   { $$ = "~"; }
+               | '&'                   { $$ = "&"; }
+               | '#'                   { $$ = "#"; }
                | '|'                   { $$ = "|"; }
                | '<'                   { $$ = "<"; }
                | '>'                   { $$ = ">"; }
@@ -4462,6 +4468,8 @@
                                {       $$ = makeA_Expr(OP, "+", NULL, $2); }
                | '-' a_expr %prec UMINUS
                                {       $$ = doNegate($2); }
+               | '~' a_expr %prec UMINUS
+                               {       $$ = makeA_Expr(OP, "~", NULL, $2); }
                | '%' a_expr
                                {       $$ = makeA_Expr(OP, "%", NULL, $2); }
                | '^' a_expr
@@ -4484,6 +4492,10 @@
                                {       $$ = makeA_Expr(OP, "/", $1, $3); }
                | a_expr '%' a_expr
                                {       $$ = makeA_Expr(OP, "%", $1, $3); }
+               | a_expr '&' a_expr
+                               {       $$ = makeA_Expr(OP, "&", $1, $3); }
+               | a_expr '#' a_expr
+                               {       $$ = makeA_Expr(OP, "#", $1, $3); }
                | a_expr '^' a_expr
                                {       $$ = makeA_Expr(OP, "^", $1, $3); }
                | a_expr '|' a_expr
@@ -4716,6 +4728,8 @@
                                {       $$ = makeA_Expr(OP, "+", NULL, $2); }
                | '-' b_expr %prec UMINUS
                                {       $$ = doNegate($2); }
+               | '~' b_expr %prec UMINUS
+                               {       $$ = makeA_Expr(OP, "~", NULL, $2); }
                | '%' b_expr
                                {       $$ = makeA_Expr(OP, "%", NULL, $2); }
                | '^' b_expr
@@ -4738,6 +4752,10 @@
                                {       $$ = makeA_Expr(OP, "/", $1, $3); }
                | b_expr '%' b_expr
                                {       $$ = makeA_Expr(OP, "%", $1, $3); }
+               | b_expr '&' b_expr
+                               {       $$ = makeA_Expr(OP, "&", $1, $3); }
+               | b_expr '#' b_expr
+                               {       $$ = makeA_Expr(OP, "#", $1, $3); }
                | b_expr '^' b_expr
                                {       $$ = makeA_Expr(OP, "^", $1, $3); }
                | b_expr '|' b_expr
Index: pgsql/src/backend/utils/adt/int.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/adt/int.c,v
retrieving revision 1.42
diff -u -r1.42 int.c
--- pgsql/src/backend/utils/adt/int.c   2000/08/01 18:29:35     1.42
+++ pgsql/src/backend/utils/adt/int.c   2000/09/20 19:04:58
@@ -843,3 +843,83 @@
 
        PG_RETURN_INT32((arg1 < arg2) ? arg1 : arg2);
 }
+
+/* Binary arithmetics
+ *
+ *             int[24]and              - returns arg1 & arg2
+ *             int[24]or               - returns arg1 | arg2
+ *             int[24]xor              - returns arg1 ^ arg2
+ *             int[24]not              - returns ~arg1
+ */
+
+Datum
+int4and(PG_FUNCTION_ARGS)
+{
+       int32           arg1 = PG_GETARG_INT32(0);
+       int32           arg2 = PG_GETARG_INT32(1);
+
+       PG_RETURN_INT32(arg1 & arg2);
+}
+
+Datum
+int4or(PG_FUNCTION_ARGS)
+{
+       int32           arg1 = PG_GETARG_INT32(0);
+       int32           arg2 = PG_GETARG_INT32(1);
+
+       PG_RETURN_INT32(arg1 | arg2);
+}
+
+Datum
+int4xor(PG_FUNCTION_ARGS)
+{
+       int32           arg1 = PG_GETARG_INT32(0);
+       int32           arg2 = PG_GETARG_INT32(1);
+
+       PG_RETURN_INT32(arg1 ^ arg2);
+}
+
+Datum
+int4not(PG_FUNCTION_ARGS)
+{
+       int32           arg1 = PG_GETARG_INT32(0);
+
+       PG_RETURN_INT32(~arg1);
+}
+
+Datum
+int2and(PG_FUNCTION_ARGS)
+{
+       int16           arg1 = PG_GETARG_INT16(0);
+       int16           arg2 = PG_GETARG_INT16(1);
+
+       PG_RETURN_INT16(arg1 & arg2);
+}
+
+Datum
+int2or(PG_FUNCTION_ARGS)
+{
+       int16           arg1 = PG_GETARG_INT16(0);
+       int16           arg2 = PG_GETARG_INT16(1);
+
+       PG_RETURN_INT16(arg1 | arg2);
+}
+
+Datum
+int2xor(PG_FUNCTION_ARGS)
+{
+       int16           arg1 = PG_GETARG_INT16(0);
+       int16           arg2 = PG_GETARG_INT16(1);
+
+       PG_RETURN_INT16(arg1 ^ arg2);
+}
+
+Datum
+int2not(PG_FUNCTION_ARGS)
+{
+       int16           arg1 = PG_GETARG_INT16(0);
+
+       PG_RETURN_INT16(~arg1);
+}
+
+
Index: pgsql/src/backend/utils/adt/int8.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/adt/int8.c,v
retrieving revision 1.24
diff -u -r1.24 int8.c
--- pgsql/src/backend/utils/adt/int8.c  2000/07/28 05:07:41     1.24
+++ pgsql/src/backend/utils/adt/int8.c  2000/09/20 19:04:59
@@ -591,6 +591,48 @@
        PG_RETURN_INT64(val1 / val2);
 }
 
+/* Binary arithmetics
+ *
+ *             int8and         - returns arg1 & arg2
+ *             int8or          - returns arg1 | arg2
+ *             int8xor         - returns arg1 ^ arg2
+ *             int8not         - returns ~arg1
+ */
+
+Datum
+int8and(PG_FUNCTION_ARGS)
+{
+       int64           arg1 = PG_GETARG_INT64(0);
+       int64           arg2 = PG_GETARG_INT64(1);
+
+       PG_RETURN_INT64(arg1 & arg2);
+}
+
+Datum
+int8or(PG_FUNCTION_ARGS)
+{
+       int64           arg1 = PG_GETARG_INT64(0);
+       int64           arg2 = PG_GETARG_INT64(1);
+
+       PG_RETURN_INT64(arg1 | arg2);
+}
+
+Datum
+int8xor(PG_FUNCTION_ARGS)
+{
+       int64           arg1 = PG_GETARG_INT64(0);
+       int64           arg2 = PG_GETARG_INT64(1);
+
+       PG_RETURN_INT64(arg1 ^ arg2);
+}
+
+Datum
+int8not(PG_FUNCTION_ARGS)
+{
+       int64           arg1 = PG_GETARG_INT64(0);
+
+       PG_RETURN_INT64(~arg1);
+}
 
 /*----------------------------------------------------------
  *     Conversion operators.
Index: pgsql/src/include/catalog/pg_operator.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/catalog/pg_operator.h,v
retrieving revision 1.82
diff -u -r1.82 pg_operator.h
--- pgsql/src/include/catalog/pg_operator.h     2000/09/15 18:45:27     1.82
+++ pgsql/src/include/catalog/pg_operator.h     2000/09/20 19:05:03
@@ -754,6 +754,19 @@
 DATA(insert OID = 1872 ( "<="     PGUID 0 b t f  20  21  16  1867 1871   0  0 int82le 
scalarltsel scalarltjoinsel ));
 DATA(insert OID = 1873 ( ">="     PGUID 0 b t f  20  21  16  1866 1870   0  0 int82ge 
scalargtsel scalargtjoinsel ));
 
+DATA(insert OID = 1890 ( "&"      PGUID 0 b t f  21  21  21 1892   0   0   0 int2and 
+- - ));
+DATA(insert OID = 1891 ( "|"      PGUID 0 b t f  21  21  21 1891   0   0   0 int2or - 
+- ));
+DATA(insert OID = 1892 ( "#"      PGUID 0 b t f  21  21  21 1890   0   0   0 int2xor 
+- - ));
+DATA(insert OID = 1893 ( "~"      PGUID 0 l t f   0  21  21    0   0   0   0 int2not 
+- - ));
+DATA(insert OID = 1894 ( "&"      PGUID 0 b t f  23  23  23 1895   0   0   0 int4and 
+- - ));
+DATA(insert OID = 1895 ( "|"      PGUID 0 b t f  23  23  23 1894   0   0   0 int4or - 
+- ));
+DATA(insert OID = 1896 ( "#"      PGUID 0 b t f  23  23  23 1893   0   0   0 int4xor 
+- - ));
+DATA(insert OID = 1897 ( "~"      PGUID 0 l t f   0  23  23    0   0   0   0 int4not 
+- - ));
+DATA(insert OID = 1898 ( "&"      PGUID 0 b t f  20  20  20 1898   0   0   0 int8and 
+- - ));
+DATA(insert OID = 1899 ( "|"      PGUID 0 b t f  20  20  20 1897   0   0   0 int8or - 
+- ));
+DATA(insert OID = 1900 ( "#"      PGUID 0 b t f  20  20  20 1896   0   0   0 int8xor 
+- - ));
+DATA(insert OID = 1901 ( "~"      PGUID 0 l t f   0  20  20    0   0   0   0 int8not 
+- - ));
+
 /*
  * function prototypes
  */
Index: pgsql/src/include/catalog/pg_proc.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.167
diff -u -r1.167 pg_proc.h
--- pgsql/src/include/catalog/pg_proc.h 2000/09/19 18:18:01     1.167
+++ pgsql/src/include/catalog/pg_proc.h 2000/09/20 19:05:10
@@ -2511,6 +2511,32 @@
 DATA(insert OID = 1861 (  int82ge                 PGUID 12 f t t t 2 f 16 "20 21" 100 
0 0 100  int82ge - ));
 DESCR("greater-than-or-equal");
 
+DATA(insert OID = 1902 (  int2and                 PGUID 12 f t t t 2 f 21 "21 21" 100 
+0 0 100  int2and - ));
+DESCR("binary AND");
+DATA(insert OID = 1903 (  int2or                  PGUID 12 f t t t 2 f 21 "21 21" 100 
+0 0 100  int2or - ));
+DESCR("binary OR");
+DATA(insert OID = 1904 (  int2xor                 PGUID 12 f t t t 2 f 21 "21 21" 100 
+0 0 100  int2xor - ));
+DESCR("binary XOR");
+DATA(insert OID = 1905 (  int2not                 PGUID 12 f t t t 1 f 21 "21" 100 0 
+0 100  int2not - ));
+DESCR("binary NOT");
+
+DATA(insert OID = 1906 (  int4and                 PGUID 12 f t t t 2 f 23 "23 23" 100 
+0 0 100  int4and - ));
+DESCR("binary AND");
+DATA(insert OID = 1907 (  int4or                  PGUID 12 f t t t 2 f 23 "23 23" 100 
+0 0 100  int4or - ));
+DESCR("binary OR");
+DATA(insert OID = 1908 (  int4xor                 PGUID 12 f t t t 2 f 23 "23 23" 100 
+0 0 100  int4xor - ));
+DESCR("binary XOR");
+DATA(insert OID = 1909 (  int4not                 PGUID 12 f t t t 1 f 23 "23" 100 0 
+0 100  int4not - ));
+DESCR("binary NOT");
+
+DATA(insert OID = 1910 (  int8and                 PGUID 12 f t t t 2 f 20 "20 20" 100 
+0 0 100  int8and - ));
+DESCR("binary AND");
+DATA(insert OID = 1911 (  int8or                  PGUID 12 f t t t 2 f 20 "20 20" 100 
+0 0 100  int8or - ));
+DESCR("binary OR");
+DATA(insert OID = 1912 (  int8xor                 PGUID 12 f t t t 2 f 20 "20 20" 100 
+0 0 100  int8xor - ));
+DESCR("binary XOR");
+DATA(insert OID = 1913 (  int8not                 PGUID 12 f t t t 1 f 20 "20" 100 0 
+0 100  int8not - ));
+DESCR("binary NOT");
 
 /*
  * prototypes for functions pg_proc.c
Index: pgsql/src/include/utils/builtins.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/utils/builtins.h,v
retrieving revision 1.138
diff -u -r1.138 builtins.h
--- pgsql/src/include/utils/builtins.h  2000/09/19 18:18:02     1.138
+++ pgsql/src/include/utils/builtins.h  2000/09/20 19:05:12
@@ -127,6 +127,15 @@
 extern Datum int4larger(PG_FUNCTION_ARGS);
 extern Datum int4smaller(PG_FUNCTION_ARGS);
 
+extern Datum int4and(PG_FUNCTION_ARGS);
+extern Datum int4or(PG_FUNCTION_ARGS);
+extern Datum int4xor(PG_FUNCTION_ARGS);
+extern Datum int4not(PG_FUNCTION_ARGS);
+extern Datum int2and(PG_FUNCTION_ARGS);
+extern Datum int2or(PG_FUNCTION_ARGS);
+extern Datum int2xor(PG_FUNCTION_ARGS);
+extern Datum int2not(PG_FUNCTION_ARGS);
+
 /* name.c */
 extern Datum namein(PG_FUNCTION_ARGS);
 extern Datum nameout(PG_FUNCTION_ARGS);
Index: pgsql/src/include/utils/int8.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/utils/int8.h,v
retrieving revision 1.23
diff -u -r1.23 int8.h
--- pgsql/src/include/utils/int8.h      2000/07/28 05:07:44     1.23
+++ pgsql/src/include/utils/int8.h      2000/09/20 19:05:12
@@ -76,6 +76,11 @@
 extern Datum int8larger(PG_FUNCTION_ARGS);
 extern Datum int8smaller(PG_FUNCTION_ARGS);
 
+extern Datum int8and(PG_FUNCTION_ARGS);
+extern Datum int8or(PG_FUNCTION_ARGS);
+extern Datum int8xor(PG_FUNCTION_ARGS);
+extern Datum int8not(PG_FUNCTION_ARGS);
+
 extern Datum int84pl(PG_FUNCTION_ARGS);
 extern Datum int84mi(PG_FUNCTION_ARGS);
 extern Datum int84mul(PG_FUNCTION_ARGS);

Reply via email to