*** 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);