@ -9,7 +9,7 @@
* Portions Copyright ( c ) 1994 , Regents of the University of California
*
* IDENTIFICATION
* $ Header : / cvsroot / pgsql / src / backend / utils / adt / varbit . c , v 1.17 2001 / 05 / 03 19 : 00 : 36 tgl Exp $
* $ Header : / cvsroot / pgsql / src / backend / utils / adt / varbit . c , v 1.18 2001 / 05 / 22 16 : 37 : 16 petere Exp $
*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
@ -25,10 +25,6 @@
/*----------
* Prefixes :
* zp - - zero - padded fixed length bit string
* var - - varying bit string
*
* attypmod - - contains the length of the bit string in bits , or for
* varying bits the maximum length .
*
@ -42,13 +38,13 @@
*/
/*
* zp bit_in -
* bit_in -
* converts a char string to the internal representation of a bitstring .
* The length is determined by the number of bits required plus
* VARHDRSZ bytes or from atttypmod .
*/
Datum
zp bit_in( PG_FUNCTION_ARGS )
bit_in ( PG_FUNCTION_ARGS )
{
char * input_string = PG_GETARG_CSTRING ( 0 ) ;
@ -64,8 +60,7 @@ zpbit_in(PG_FUNCTION_ARGS)
bitlen , /* Number of bits in the bit string */
slen ; /* Length of the input string */
bool bit_not_hex ; /* false = hex string true = bit string */
int bc ,
ipad ;
int bc ;
bits8 x = 0 ;
/* Check that the first character is a b or an x */
@ -99,15 +94,12 @@ zpbit_in(PG_FUNCTION_ARGS)
/*
* Sometimes atttypmod is not supplied . If it is supplied we need to
* make sure that the bitstring fits . Note that the number of infered
* bits can be larger than the number of actual bits needed , but only
* if we are reading a hex string and not by more than 3 bits , as a
* hex string gives an accurate length up to 4 bits
* make sure that the bitstring fits .
*/
if ( atttypmod < = 0 )
atttypmod = bitlen ;
else if ( bit_not_hex ? ( bitlen > atttypmod ) : ( bitlen > atttypmod + 3 ) )
elog ( ERROR , " zpbit_in: bit string too long for bit(%d)" ,
else if ( bitlen ! = atttypmod )
elog ( ERROR , " bit string length does not match type bit(%d)" ,
atttypmod ) ;
len = VARBITTOTALLEN ( atttypmod ) ;
@ -128,7 +120,7 @@ zpbit_in(PG_FUNCTION_ARGS)
if ( * sp = = ' 1 ' )
* r | = x ;
else if ( * sp ! = ' 0 ' )
elog ( ERROR , " C annot parse %c as a binary digit" , * sp ) ;
elog ( ERROR , " c annot parse %c as a binary digit" , * sp ) ;
x > > = 1 ;
if ( x = = 0 )
{
@ -149,7 +141,7 @@ zpbit_in(PG_FUNCTION_ARGS)
else if ( * sp > = ' a ' & & * sp < = ' f ' )
x = ( bits8 ) ( * sp - ' a ' ) + 10 ;
else
elog ( ERROR , " C annot parse %c as a hex digit" , * sp ) ;
elog ( ERROR , " c annot parse %c as a hex digit" , * sp ) ;
if ( bc )
{
* r + + | = x ;
@ -163,31 +155,12 @@ zpbit_in(PG_FUNCTION_ARGS)
}
}
if ( bitlen > atttypmod )
{
/* Check that this fitted */
r = VARBITEND ( result ) - 1 ;
ipad = VARBITPAD ( result ) ;
/*
* The bottom ipad bits of the byte pointed to by r need to be
* zero
*/
if ( ( ( * r < < ( BITS_PER_BYTE - ipad ) ) & BITMASK ) ! = 0 )
elog ( ERROR , " zpbit_in: bit string too long for bit(%d) " ,
atttypmod ) ;
}
PG_RETURN_VARBIT_P ( result ) ;
}
/* zpbit_out -
* for the time being we print everything as hex strings , as this is likely
* to be more compact than bit strings , and consequently much more efficient
* for long strings
*/
Datum
zp bit_out( PG_FUNCTION_ARGS )
bit_out ( PG_FUNCTION_ARGS )
{
# if 1
/* same as varbit output */
@ -228,69 +201,59 @@ zpbit_out(PG_FUNCTION_ARGS)
# endif
}
/* zp bit()
/* bit()
* Converts a bit ( ) type to a specific internal length .
* len is the bitlength specified in the column definition .
*/
Datum
zp bit( PG_FUNCTION_ARGS )
bit ( PG_FUNCTION_ARGS )
{
VarBit * arg = PG_GETARG_VARBIT_P ( 0 ) ;
int32 len = PG_GETARG_INT32 ( 1 ) ;
VarBit * result ;
int rlen ;
/* No work if typmod is invalid or supplied data matches it already */
if ( len < = 0 | | len = = VARBITLEN ( arg ) )
PG_RETURN_VARBIT_P ( arg ) ;
rlen = VARBITTOTALLEN ( len ) ;
result = ( VarBit * ) palloc ( rlen ) ;
/* set to 0 so that result is zero-padded if input is shorter */
memset ( result , 0 , rlen ) ;
VARATT_SIZEP ( result ) = rlen ;
VARBITLEN ( result ) = len ;
memcpy ( VARBITS ( result ) , VARBITS ( arg ) ,
Min ( VARBITBYTES ( result ) , VARBITBYTES ( arg ) ) ) ;
PG_RETURN_VARBIT_P ( result ) ;
else
elog ( ERROR , " bit string length does not match type bit(%d) " ,
len ) ;
return 0 ; /* quiet compiler */
}
/* _zp bit()
/* _bit()
* Converts an array of bit ( ) elements to a specific internal length .
* len is the bitlength specified in the column definition .
*/
Datum
_zp bit ( PG_FUNCTION_ARGS )
_bit ( PG_FUNCTION_ARGS )
{
ArrayType * v = ( ArrayType * ) PG_GETARG_VARLENA_P ( 0 ) ;
int32 len = PG_GETARG_INT32 ( 1 ) ;
FunctionCallInfoData locfcinfo ;
/*
* Since zp bit( ) is a built - in function , we should only need to look
* Since bit ( ) is a built - in function , we should only need to look
* it up once per run .
*/
static FmgrInfo zp bit_finfo;
static FmgrInfo bit_finfo ;
if ( zp bit_finfo. fn_oid = = InvalidOid )
fmgr_info ( F_ZP BIT , & zp bit_finfo) ;
if ( bit_finfo . fn_oid = = InvalidOid )
fmgr_info ( F_BIT , & bit_finfo ) ;
MemSet ( & locfcinfo , 0 , sizeof ( locfcinfo ) ) ;
locfcinfo . flinfo = & zp bit_finfo;
locfcinfo . flinfo = & bit_finfo ;
locfcinfo . nargs = 2 ;
/* We assume we are "strict" and need not worry about null inputs */
locfcinfo . arg [ 0 ] = PointerGetDatum ( v ) ;
locfcinfo . arg [ 1 ] = Int32GetDatum ( len ) ;
return array_map ( & locfcinfo , ZP BITOID, ZP BITOID) ;
return array_map ( & locfcinfo , BITOID , BITOID ) ;
}
/*
* varbit_in -
* converts a string to the internal representation of a bitstring .
* This is the same as zp bit_in except that atttypmod is taken as
* This is the same as bit_in except that atttypmod is taken as
* the maximum length , not the exact length to force the bitstring to .
*/
Datum
@ -310,8 +273,7 @@ varbit_in(PG_FUNCTION_ARGS)
bitlen , /* Number of bits in the bit string */
slen ; /* Length of the input string */
bool bit_not_hex ; /* false = hex string true = bit string */
int bc ,
ipad ;
int bc ;
bits8 x = 0 ;
/* Check that the first character is a b or an x */
@ -340,15 +302,12 @@ varbit_in(PG_FUNCTION_ARGS)
/*
* Sometimes atttypmod is not supplied . If it is supplied we need to
* make sure that the bitstring fits . Note that the number of infered
* bits can be larger than the number of actual bits needed , but only
* if we are reading a hex string and not by more than 3 bits , as a
* hex string gives an accurate length up to 4 bits
* make sure that the bitstring fits .
*/
if ( atttypmod < = 0 )
atttypmod = bitlen ;
else if ( bit_not_hex ? ( bit len > atttypmod ) : ( bitlen > atttypmod + 3 ) )
elog ( ERROR , " varbit_in: bit string too long for bit varying(%d)" ,
else if ( bitlen > atttypmod )
elog ( ERROR , " bit string too long for type bit varying(%d) " ,
atttypmod ) ;
len = VARBITTOTALLEN ( bitlen ) ;
@ -369,7 +328,7 @@ varbit_in(PG_FUNCTION_ARGS)
if ( * sp = = ' 1 ' )
* r | = x ;
else if ( * sp ! = ' 0 ' )
elog ( ERROR , " C annot parse %c as a binary digit" , * sp ) ;
elog ( ERROR , " c annot parse %c as a binary digit" , * sp ) ;
x > > = 1 ;
if ( x = = 0 )
{
@ -390,7 +349,7 @@ varbit_in(PG_FUNCTION_ARGS)
else if ( * sp > = ' a ' & & * sp < = ' f ' )
x = ( bits8 ) ( * sp - ' a ' ) + 10 ;
else
elog ( ERROR , " C annot parse %c as a hex digit" , * sp ) ;
elog ( ERROR , " c annot parse %c as a hex digit" , * sp ) ;
if ( bc )
{
* r + + | = x ;
@ -404,21 +363,6 @@ varbit_in(PG_FUNCTION_ARGS)
}
}
if ( bitlen > atttypmod )
{
/* Check that this fitted */
r = VARBITEND ( result ) - 1 ;
ipad = VARBITPAD ( result ) ;
/*
* The bottom ipad bits of the byte pointed to by r need to be
* zero
*/
if ( ( ( * r < < ( BITS_PER_BYTE - ipad ) ) & BITMASK ) ! = 0 )
elog ( ERROR , " varbit_in: bit string too long for bit varying(%d) " ,
atttypmod ) ;
}
PG_RETURN_VARBIT_P ( result ) ;
}
@ -477,6 +421,9 @@ varbit(PG_FUNCTION_ARGS)
if ( len < = 0 | | len > = VARBITLEN ( arg ) )
PG_RETURN_VARBIT_P ( arg ) ;
if ( len < VARBITLEN ( arg ) )
elog ( ERROR , " bit string too long for type bit varying(%d) " , len ) ;
rlen = VARBITTOTALLEN ( len ) ;
result = ( VarBit * ) palloc ( rlen ) ;
VARATT_SIZEP ( result ) = rlen ;
@ -868,7 +815,7 @@ bitand(PG_FUNCTION_ARGS)
bitlen1 = VARBITLEN ( arg1 ) ;
bitlen2 = VARBITLEN ( arg2 ) ;
if ( bitlen1 ! = bitlen2 )
elog ( ERROR , " bitand: Cannot AND bit strings of different sizes" ) ;
elog ( ERROR , " cannot AND bit strings of different sizes" ) ;
len = VARSIZE ( arg1 ) ;
result = ( VarBit * ) palloc ( len ) ;
VARATT_SIZEP ( result ) = len ;
@ -906,7 +853,7 @@ bitor(PG_FUNCTION_ARGS)
bitlen1 = VARBITLEN ( arg1 ) ;
bitlen2 = VARBITLEN ( arg2 ) ;
if ( bitlen1 ! = bitlen2 )
elog ( ERROR , " bitor: Cannot OR bit strings of different sizes" ) ;
elog ( ERROR , " cannot OR bit strings of different sizes" ) ;
len = VARSIZE ( arg1 ) ;
result = ( VarBit * ) palloc ( len ) ;
VARATT_SIZEP ( result ) = len ;
@ -950,7 +897,7 @@ bitxor(PG_FUNCTION_ARGS)
bitlen1 = VARBITLEN ( arg1 ) ;
bitlen2 = VARBITLEN ( arg2 ) ;
if ( bitlen1 ! = bitlen2 )
elog ( ERROR , " bitxor: Cannot XOR bit strings of different sizes" ) ;
elog ( ERROR , " cannot XOR bit strings of different sizes" ) ;
len = VARSIZE ( arg1 ) ;
result = ( VarBit * ) palloc ( len ) ;
VARATT_SIZEP ( result ) = len ;
@ -1165,7 +1112,7 @@ bittoint4(PG_FUNCTION_ARGS)
/* Check that the bit string is not too long */
if ( VARBITLEN ( arg ) > sizeof ( int4 ) * BITS_PER_BYTE )
elog ( ERROR , " Bit string is too large to fit in an int4 " ) ;
elog ( ERROR , " bit string is too large to fit in type integer " ) ;
result = 0 ;
for ( r = VARBITS ( arg ) ; r < VARBITEND ( arg ) ; r + + )
{