> This patch no longer applies.  Could you rebase it?

Done (I think). Added a couple of simple tests for bit overlay.

I didn't include the catversion.h changes: obviously the CATALOG_VERSION_NO has 
to be changed.


Leonardo


      
Index: src/backend/utils/adt/varbit.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/varbit.c,v
retrieving revision 1.63
diff -c -r1.63 varbit.c
*** src/backend/utils/adt/varbit.c      7 Jan 2010 20:17:43 -0000       1.63
--- src/backend/utils/adt/varbit.c      18 Jan 2010 09:05:50 -0000
***************
*** 1606,1608 ****
--- 1606,1704 ----
        }
        PG_RETURN_INT32(0);
  }
+ 
+ 
+ /* bitsetbit
+  * Given an instance of type 'bit' creates a new one with
+  * the Nth bit set to the given value.
+  */
+ Datum
+ bitsetbit(PG_FUNCTION_ARGS)
+ {
+       VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
+       int32           n = PG_GETARG_INT32(1);
+       int32           newBit = PG_GETARG_INT32(2);
+       VarBit     *result;
+       int                     len,
+                               bitlen;
+       bits8      *r,
+                          *p;
+       int                     byteNo,
+                               bitNo;
+       int                     oldByte,
+                               newByte;
+ 
+       bitlen = VARBITLEN(arg1);
+       if (n < 0 || n >= bitlen)
+               ereport(ERROR,
+                               (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+                                errmsg("index %d out of valid range, 0..%d",
+                                               n, bitlen - 1)));
+       /*
+        * sanity check!
+        */
+       if (newBit != 0 && newBit != 1)
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                                errmsg("new bit must be 0 or 1")));
+ 
+       len = VARSIZE(arg1);
+       result = (VarBit *) palloc(len);
+       SET_VARSIZE(result, len);
+       VARBITLEN(result) = bitlen;
+ 
+       p = VARBITS(arg1);
+       r = VARBITS(result);
+ 
+       memcpy(r, p, VARBITBYTES(arg1));
+ 
+       byteNo = n / BITS_PER_BYTE;
+       bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
+ 
+       /*
+        * Update the byte.
+        */
+       oldByte = ((unsigned char *) r)[byteNo];
+ 
+       if (newBit == 0)
+               newByte = oldByte & (~(1 << bitNo));
+       else
+               newByte = oldByte | (1 << bitNo);
+ 
+       ((unsigned char *) r)[byteNo] = newByte;
+ 
+       PG_RETURN_VARBIT_P(result);
+ }
+ 
+ /* bitgetbit
+  * returns the value of the Nth bit (0 or 1).
+  */
+ Datum
+ bitgetbit(PG_FUNCTION_ARGS)
+ {
+       VarBit     *arg1 = PG_GETARG_VARBIT_P(0);
+       int32           n = PG_GETARG_INT32(1);
+       int                     bitlen;
+       int                     byteNo,
+                               bitNo;
+       int byte;
+ 
+       bitlen = VARBITLEN(arg1);
+ 
+       if (n < 0 || n >= bitlen)
+               ereport(ERROR,
+                               (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
+                                errmsg("index %d out of valid range, 0..%d",
+                                               n, bitlen - 1)));
+ 
+       byteNo = n / BITS_PER_BYTE;
+       bitNo = BITS_PER_BYTE - 1 - n % BITS_PER_BYTE;
+ 
+       byte = ((unsigned char *) VARBITS(arg1))[byteNo];
+ 
+       if (byte &(1 << bitNo))
+               PG_RETURN_INT32(1);
+       else
+               PG_RETURN_INT32(0);
+ }
+ 
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.562
diff -c -r1.562 pg_proc.h
*** src/include/catalog/pg_proc.h       15 Jan 2010 09:19:07 -0000      1.562
--- src/include/catalog/pg_proc.h       18 Jan 2010 09:05:58 -0000
***************
*** 2405,2410 ****
--- 2405,2418 ----
  DATA(insert OID = 1699 (  substring                   PGNSP PGUID 12 1 0 0 f 
f f t f i 2 0 1560 "1560 23" _null_ _null_ _null_ _null_ bitsubstr_no_len 
_null_ _null_ _null_ ));
  DESCR("return portion of bitstring");
  
+ DATA(insert OID = 3030 (  overlay                     PGNSP PGUID 14 1 0 0 f 
f f t f i 4 0 1560 "1560 1560 23 23" _null_ _null_ _null_ _null_ "select 
pg_catalog.substring($1, 1, ($3 - 1)) || $2 || pg_catalog.substring($1, ($3 + 
$4))" _null_ _null_ _null_ ));
+ DESCR("substitute portion of bit string");
+ DATA(insert OID = 3031 (  overlay                     PGNSP PGUID 14 1 0 0 f 
f f t f i 3 0 1560 "1560 1560 23" _null_ _null_ _null_ _null_    "select 
pg_catalog.substring($1, 1, ($3 - 1)) || $2 || pg_catalog.substring($1, ($3 + 
pg_catalog.length($2)))" _null_ _null_ _null_ ));
+ DESCR("substitute portion of bit string");
+ DATA(insert OID = 3032 (  get_bit                PGNSP PGUID 12 1 0 0 f f f t 
f i 2 0 23 "1560 23" _null_ _null_ _null_ _null_ bitgetbit _null_ _null_ _null_ 
));
+ DESCR("get bit");
+ DATA(insert OID = 3033 (  set_bit                PGNSP PGUID 12 1 0 0 f f f t 
f i 3 0 1560 "1560 23 23" _null_ _null_ _null_ _null_ bitsetbit _null_ _null_ 
_null_ ));
+ DESCR("set bit");
  
  /* for mac type support */
  DATA(insert OID = 436 (  macaddr_in                   PGNSP PGUID 12 1 0 0 f 
f f t f i 1 0 829 "2275" _null_ _null_ _null_ _null_ macaddr_in _null_ _null_ 
_null_ ));
Index: src/test/regress/expected/bit.out
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/expected/bit.out,v
retrieving revision 1.4
diff -c -r1.4 bit.out
*** src/test/regress/expected/bit.out   27 Jul 2003 04:53:11 -0000      1.4
--- src/test/regress/expected/bit.out   18 Jan 2010 09:05:59 -0000
***************
*** 509,511 ****
--- 509,547 ----
  
  DROP TABLE BIT_SHIFT_TABLE;
  DROP TABLE VARBIT_SHIFT_TABLE;
+ SELECT get_bit(B'0101011000100', 10);
+  get_bit 
+ ---------
+        1
+ (1 row)
+ 
+ SELECT get_bit(B'0101011', 3);
+  get_bit 
+ ---------
+        1
+ (1 row)
+ 
+ SELECT set_bit(B'0101011', 0, 1);
+  set_bit 
+ ---------
+  1101011
+ (1 row)
+ 
+ SELECT set_bit(B'010101100010010', 14, 1);
+      set_bit     
+ -----------------
+  010101100010011
+ (1 row)
+ 
+ SELECT overlay(B'0101011100' placing '001' from 2 for 3);
+   overlay   
+ ------------
+  0001011100
+ (1 row)
+ 
+ SELECT overlay(B'0101011100' placing '101' from 6);
+   overlay   
+ ------------
+  0101010100
+ (1 row)
+ 
Index: src/test/regress/sql/bit.sql
===================================================================
RCS file: /projects/cvsroot/pgsql/src/test/regress/sql/bit.sql,v
retrieving revision 1.2
diff -c -r1.2 bit.sql
*** src/test/regress/sql/bit.sql        22 May 2001 16:37:17 -0000      1.2
--- src/test/regress/sql/bit.sql        18 Jan 2010 09:05:59 -0000
***************
*** 184,186 ****
--- 184,193 ----
  
  DROP TABLE BIT_SHIFT_TABLE;
  DROP TABLE VARBIT_SHIFT_TABLE;
+ 
+ SELECT get_bit(B'0101011000100', 10);
+ SELECT get_bit(B'0101011', 3);
+ SELECT set_bit(B'0101011', 0, 1);
+ SELECT set_bit(B'010101100010010', 14, 1);
+ SELECT overlay(B'0101011100' placing '001' from 2 for 3);
+ SELECT overlay(B'0101011100' placing '101' from 6);
\ No newline at end of file
Index: src/include/utils/varbit.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/varbit.h,v
retrieving revision 1.30
diff -c -r1.30 varbit.h
*** src/include/utils/varbit.h  7 Jan 2010 20:17:44 -0000       1.30
--- src/include/utils/varbit.h  18 Jan 2010 09:05:59 -0000
***************
*** 96,100 ****
--- 96,102 ----
  extern Datum bitfromint8(PG_FUNCTION_ARGS);
  extern Datum bittoint8(PG_FUNCTION_ARGS);
  extern Datum bitposition(PG_FUNCTION_ARGS);
+ extern Datum bitsetbit(PG_FUNCTION_ARGS);
+ extern Datum bitgetbit(PG_FUNCTION_ARGS);
  
  #endif
Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.496
diff -c -r1.496 func.sgml
*** doc/src/sgml/func.sgml      15 Jan 2010 09:18:58 -0000      1.496
--- doc/src/sgml/func.sgml      18 Jan 2010 09:05:50 -0000
***************
*** 2934,2940 ****
      <literal><function>bit_length</function></literal>,
      <literal><function>octet_length</function></literal>,
      <literal><function>position</function></literal>,
!     <literal><function>substring</function></literal>.
     </para>
  
     <para>
--- 2934,2943 ----
      <literal><function>bit_length</function></literal>,
      <literal><function>octet_length</function></literal>,
      <literal><function>position</function></literal>,
!     <literal><function>substring</function></literal>,
!     <literal><function>overlay</function></literal>,
!     <literal><function>get_bit</function></literal>,
!     <literal><function>set_bit</function></literal>.
     </para>
  
     <para>
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to