varbit.c.patch

text/plain

Filename: varbit.c.patch
Type: text/plain
Part: 1
Message: Re: Re: BIT/BIT VARYING status
*** src/backend/utils/adt/varbit.c.old	Sun Nov  5 12:03:04 2000
--- src/backend/utils/adt/varbit.c	Sun Nov  5 19:12:10 2000
***************
*** 73,79 ****
  		bit_not_hex = false;
  	else
  	{
! 		elog(ERROR, "zpbit_in: %s is not a valid bitstring", s);
  		bit_not_hex = false;	/* keep compiler quiet */
  	}
  
--- 73,79 ----
  		bit_not_hex = false;
  	else
  	{
! 		elog(ERROR, "zpbit_in: The bit string %s must start with B or X", s);
  		bit_not_hex = false;	/* keep compiler quiet */
  	}
  
***************
*** 299,305 ****
  		bit_not_hex = false;
  	else
  	{
! 		elog(ERROR, "varbit_in: %s is not a valid bitstring", s);
  		bit_not_hex = false;	/* keep compiler quiet */
  	}
  
--- 299,305 ----
  		bit_not_hex = false;
  	else
  	{
! 		elog(ERROR, "varbit_in: The bit string %s must start with B or X", s);
  		bit_not_hex = false;	/* keep compiler quiet */
  	}
  
***************
*** 744,749 ****
--- 744,752 ----
  			   *ps;
  
  	bitlen = VARBITLEN(arg);
+ 	/* Do we have an upper bound? */
+ 	if (l==-1)
+ 		l = bitlen;
  	e = s + l;
  	s1 = Max(s, 1);
  	e1 = Min(e, bitlen + 1);
***************
*** 1039,1045 ****
   * do a right shift (i.e. towards the end of the string)
   */
  Datum
! bitshiftright(PG_FUNCTION_ARGS)
  {
  	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
  	int32		shft = PG_GETARG_INT32(1);
--- 1042,1048 ----
   * do a right shift (i.e. towards the end of the string)
   */
  Datum
! zpbitshiftright(PG_FUNCTION_ARGS)
  {
  	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
  	int32		shft = PG_GETARG_INT32(1);
***************
*** 1097,1102 ****
--- 1100,1166 ----
  	PG_RETURN_VARBIT_P(result);
  }
  
+ /* bitshiftright
+  * do a right shift (i.e. towards the end of the string)
+  */
+ Datum
+ /*varbitshiftright(PG_FUNCTION_ARGS)*/
+ bitshiftright(PG_FUNCTION_ARGS)
+ {
+ 	VarBit	   *arg = PG_GETARG_VARBIT_P(0);
+ 	int32		shft = PG_GETARG_INT32(1);
+ 	VarBit	   *result;
+ 	int			byte_shift,
+ 				byte_len,
+ 				ishift,
+ 				len;
+ 	bits8	   *p,
+ 			   *r;
+ 
+ 	/* Negative shift is a shift to the left */
+ 	if (shft < 0)
+ 		PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
+ 						    VarBitPGetDatum(arg),
+ 						    Int32GetDatum(-shft)));
+ 
+ 	/* When we have a varying bit string, the string may get longer */
+ 	len = VARBITLEN(arg) + shft;
+ 	byte_len = VARBITTOTALLEN(len);
+ 
+ 	result = (VarBit *) palloc(byte_len);
+ 	VARATT_SIZEP(result) = byte_len;
+ 	VARBITLEN(result) = len;
+ 	r = VARBITS(result);
+ 
+ 	byte_shift = shft / BITS_PER_BYTE;
+ 	ishift = shft % BITS_PER_BYTE;
+ 	p = VARBITS(arg);
+ 
+ 	/* Set the first part of the result to 0 */
+ 	memset(r, 0, byte_shift);
+ 	r += byte_shift;
+ 
+ 	if (ishift == 0)
+ 	{
+ 		/* Special case: we can do a memcpy */
+ 		len = VARBITBYTES(arg);
+ 		memcpy(r, p, len);
+ 	}
+ 	else
+ 	{
+ 		if (r < VARBITEND(result))
+ 			*r = 0;				/* initialize first byte */
+ 		for (; r < VARBITEND(result); p++)
+ 		{
+ 			*r |= *p >> ishift;
+ 			if ((++r) < VARBITEND(result))
+ 				*r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
+ 		}
+ 	}
+ 
+ 	PG_RETURN_VARBIT_P(result);
+ }
+ 
  /* This is not defined in any standard. We retain the natural ordering of
   * bits here, as it just seems more intuitive. 
   */
***************
*** 1216,1224 ****
  				p++;
  				if (p == VARBITEND(arg)) {
  					mask2 = end_mask << (BITS_PER_BYTE - is);
! 					is_match = mask2 == 0;
! 					elog(NOTICE,"S. %d %d em=%2x sm=%2x r=%d",
! 						 i,is,end_mask,mask2,is_match);
  					break;
  				}
  				cmp = *s << (BITS_PER_BYTE - is);
--- 1280,1286 ----
  				p++;
  				if (p == VARBITEND(arg)) {
  					mask2 = end_mask << (BITS_PER_BYTE - is);
! 					is_match = (mask2 == 0);
  					break;
  				}
  				cmp = *s << (BITS_PER_BYTE - is);