Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitce5dc56

Browse files
author
Thomas G. Lockhart
committed
Allow bit string constants without fully-specified length declaration.
Implement conversion between 8-byte integers and bit strings. Similar to what is done for 4-byte integers.
1 parentaf704cd commitce5dc56

File tree

4 files changed

+115
-45
lines changed

4 files changed

+115
-45
lines changed

‎src/backend/utils/adt/varbit.c

Lines changed: 98 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.22 2002/06/20 20:29:38 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.23 2002/08/04 06:33:48 thomas Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -98,8 +98,8 @@ bit_in(PG_FUNCTION_ARGS)
9898
if (atttypmod <=0)
9999
atttypmod=bitlen;
100100
elseif (bitlen!=atttypmod)
101-
elog(ERROR,"bit string length does not match typebit(%d)",
102-
atttypmod);
101+
elog(ERROR,"Bit string length%ddoes not match typeBIT(%d)",
102+
bitlen,atttypmod);
103103

104104
len=VARBITTOTALLEN(atttypmod);
105105
result= (VarBit*)palloc(len);
@@ -119,7 +119,7 @@ bit_in(PG_FUNCTION_ARGS)
119119
if (*sp=='1')
120120
*r |=x;
121121
elseif (*sp!='0')
122-
elog(ERROR,"cannot parse%c as a binary digit",*sp);
122+
elog(ERROR,"Cannot parse'%c' as a binary digit",*sp);
123123
x >>=1;
124124
if (x==0)
125125
{
@@ -140,7 +140,7 @@ bit_in(PG_FUNCTION_ARGS)
140140
elseif (*sp >='a'&&*sp <='f')
141141
x= (bits8) (*sp-'a')+10;
142142
else
143-
elog(ERROR,"cannot parse%c as a hex digit",*sp);
143+
elog(ERROR,"Cannot parse'%c' as a hex digit",*sp);
144144
if (bc)
145145
{
146146
*r++ |=x;
@@ -214,8 +214,8 @@ bit(PG_FUNCTION_ARGS)
214214
if (len <=0||len==VARBITLEN(arg))
215215
PG_RETURN_VARBIT_P(arg);
216216
else
217-
elog(ERROR,"bit string length does not match typebit(%d)",
218-
len);
217+
elog(ERROR,"Bit string length%ddoes not match typeBIT(%d)",
218+
VARBITLEN(arg),len);
219219
return0;/* quiet compiler */
220220
}
221221

@@ -305,7 +305,7 @@ varbit_in(PG_FUNCTION_ARGS)
305305
if (atttypmod <=0)
306306
atttypmod=bitlen;
307307
elseif (bitlen>atttypmod)
308-
elog(ERROR,"bit string too long for typebit varying(%d)",
308+
elog(ERROR,"Bit string too long for typeBIT VARYING(%d)",
309309
atttypmod);
310310

311311
len=VARBITTOTALLEN(bitlen);
@@ -326,7 +326,7 @@ varbit_in(PG_FUNCTION_ARGS)
326326
if (*sp=='1')
327327
*r |=x;
328328
elseif (*sp!='0')
329-
elog(ERROR,"cannot parse%c as a binary digit",*sp);
329+
elog(ERROR,"Cannot parse'%c' as a binary digit",*sp);
330330
x >>=1;
331331
if (x==0)
332332
{
@@ -347,7 +347,7 @@ varbit_in(PG_FUNCTION_ARGS)
347347
elseif (*sp >='a'&&*sp <='f')
348348
x= (bits8) (*sp-'a')+10;
349349
else
350-
elog(ERROR,"cannot parse%c as a hex digit",*sp);
350+
elog(ERROR,"Cannot parse'%c' as a hex digit",*sp);
351351
if (bc)
352352
{
353353
*r++ |=x;
@@ -420,7 +420,7 @@ varbit(PG_FUNCTION_ARGS)
420420
PG_RETURN_VARBIT_P(arg);
421421

422422
if (len<VARBITLEN(arg))
423-
elog(ERROR,"bit string too long for typebit varying(%d)",len);
423+
elog(ERROR,"Bit string too long for typeBIT VARYING(%d)",len);
424424

425425
rlen=VARBITTOTALLEN(len);
426426
result= (VarBit*)palloc(rlen);
@@ -812,7 +812,7 @@ bitand(PG_FUNCTION_ARGS)
812812
bitlen1=VARBITLEN(arg1);
813813
bitlen2=VARBITLEN(arg2);
814814
if (bitlen1!=bitlen2)
815-
elog(ERROR,"cannot AND bit strings of different sizes");
815+
elog(ERROR,"Cannot AND bit strings of different sizes");
816816
len=VARSIZE(arg1);
817817
result= (VarBit*)palloc(len);
818818
VARATT_SIZEP(result)=len;
@@ -850,7 +850,7 @@ bitor(PG_FUNCTION_ARGS)
850850
bitlen1=VARBITLEN(arg1);
851851
bitlen2=VARBITLEN(arg2);
852852
if (bitlen1!=bitlen2)
853-
elog(ERROR,"cannot OR bit strings of different sizes");
853+
elog(ERROR,"Cannot OR bit strings of different sizes");
854854
len=VARSIZE(arg1);
855855
result= (VarBit*)palloc(len);
856856
VARATT_SIZEP(result)=len;
@@ -894,7 +894,7 @@ bitxor(PG_FUNCTION_ARGS)
894894
bitlen1=VARBITLEN(arg1);
895895
bitlen2=VARBITLEN(arg2);
896896
if (bitlen1!=bitlen2)
897-
elog(ERROR,"cannot XOR bit strings of different sizes");
897+
elog(ERROR,"Cannot XOR bit strings of different sizes");
898898
len=VARSIZE(arg1);
899899
result= (VarBit*)palloc(len);
900900
VARATT_SIZEP(result)=len;
@@ -1109,7 +1109,7 @@ bittoint4(PG_FUNCTION_ARGS)
11091109

11101110
/* Check that the bit string is not too long */
11111111
if (VARBITLEN(arg)>sizeof(int4)*BITS_PER_BYTE)
1112-
elog(ERROR,"bit string is too large to fit in type integer");
1112+
elog(ERROR,"Bit string is too large to fit in type integer");
11131113
result=0;
11141114
for (r=VARBITS(arg);r<VARBITEND(arg);r++)
11151115
{
@@ -1122,51 +1122,114 @@ bittoint4(PG_FUNCTION_ARGS)
11221122
PG_RETURN_INT32(result);
11231123
}
11241124

1125+
Datum
1126+
bitfromint8(PG_FUNCTION_ARGS)
1127+
{
1128+
#ifndefINT64_IS_BUSTED
1129+
int64a=PG_GETARG_INT64(0);
1130+
VarBit*result;
1131+
bits8*r;
1132+
intlen;
1133+
1134+
/* allocate enough space for the bits in an int64 */
1135+
len=VARBITTOTALLEN(sizeof(a)*BITS_PER_BYTE);
1136+
result= (VarBit*)palloc(len);
1137+
VARATT_SIZEP(result)=len;
1138+
VARBITLEN(result)=sizeof(a)*BITS_PER_BYTE;
1139+
1140+
/*
1141+
* masks and shifts here are just too painful and we know that an int64
1142+
* has got 8 bytes
1143+
*/
1144+
r=VARBITS(result);
1145+
r[0]= (bits8) ((a >> (7*BITS_PER_BYTE))&BITMASK);
1146+
r[1]= (bits8) ((a >> (6*BITS_PER_BYTE))&BITMASK);
1147+
r[2]= (bits8) ((a >> (5*BITS_PER_BYTE))&BITMASK);
1148+
r[3]= (bits8) ((a >> (4*BITS_PER_BYTE))&BITMASK);
1149+
r[4]= (bits8) ((a >> (3*BITS_PER_BYTE))&BITMASK);
1150+
r[5]= (bits8) ((a >> (2*BITS_PER_BYTE))&BITMASK);
1151+
r[6]= (bits8) ((a >> (1*BITS_PER_BYTE))&BITMASK);
1152+
r[7]= (bits8) (a&BITMASK);
1153+
1154+
PG_RETURN_VARBIT_P(result);
1155+
#else
1156+
elog(ERROR,"INT64 is not supported on this platform");
1157+
PG_RETURN_NULL();
1158+
#endif
1159+
}
1160+
1161+
Datum
1162+
bittoint8(PG_FUNCTION_ARGS)
1163+
{
1164+
#ifndefINT64_IS_BUSTED
1165+
VarBit*arg=PG_GETARG_VARBIT_P(0);
1166+
uint64result;
1167+
bits8*r;
1168+
1169+
/* Check that the bit string is not too long */
1170+
if (VARBITLEN(arg)>sizeof(result)*BITS_PER_BYTE)
1171+
elog(ERROR,"Bit string is too large to fit in type int64");
1172+
result=0;
1173+
for (r=VARBITS(arg);r<VARBITEND(arg);r++)
1174+
{
1175+
result <<=BITS_PER_BYTE;
1176+
result |=*r;
1177+
}
1178+
/* Now shift the result to take account of the padding at the end */
1179+
result >>=VARBITPAD(arg);
1180+
1181+
PG_RETURN_INT64(result);
1182+
#else
1183+
elog(ERROR,"INT64 is not supported on this platform");
1184+
PG_RETURN_NULL();
1185+
#endif
1186+
}
11251187

11261188

11271189
/* Determines the position of S2 in the bitstring S1 (1-based string).
11281190
* If S2 does not appear in S1 this function returns 0.
11291191
* If S2 is of length 0 this function returns 1.
1192+
* Compatible in usage with POSITION() functions for other data types.
11301193
*/
11311194
Datum
11321195
bitposition(PG_FUNCTION_ARGS)
11331196
{
1197+
VarBit*str=PG_GETARG_VARBIT_P(0);
11341198
VarBit*substr=PG_GETARG_VARBIT_P(1);
1135-
VarBit*arg=PG_GETARG_VARBIT_P(0);
11361199
intsubstr_length,
1137-
arg_length,
1200+
str_length,
11381201
i,
11391202
is;
11401203
bits8*s,/* pointer into substring */
1141-
*p;/* pointer intoarg */
1204+
*p;/* pointer intostr */
11421205
bits8cmp,/* shifted substring byte to compare */
11431206
mask1,/* mask for substring byte shifted right */
11441207
mask2,/* mask for substring byte shifted left */
11451208
end_mask,/* pad mask for last substring byte */
1146-
arg_mask;/* pad mask for lastargument byte */
1209+
str_mask;/* pad mask for laststring byte */
11471210
boolis_match;
11481211

11491212
/* Get the substring length */
11501213
substr_length=VARBITLEN(substr);
1151-
arg_length=VARBITLEN(arg);
1214+
str_length=VARBITLEN(str);
11521215

1153-
/*Argument has0 length or substring longer thanargument, return 0 */
1154-
if (arg_length==0||substr_length>arg_length)
1216+
/*String haszero length or substring longer thanstring, return 0 */
1217+
if ((str_length==0)||(substr_length>str_length))
11551218
PG_RETURN_INT32(0);
11561219

1157-
/*0-length means return 1 */
1220+
/*zero-length substring means return 1 */
11581221
if (substr_length==0)
11591222
PG_RETURN_INT32(1);
11601223

11611224
/* Initialise the padding masks */
11621225
end_mask=BITMASK <<VARBITPAD(substr);
1163-
arg_mask=BITMASK <<VARBITPAD(arg);
1164-
for (i=0;i<VARBITBYTES(arg)-VARBITBYTES(substr)+1;i++)
1226+
str_mask=BITMASK <<VARBITPAD(str);
1227+
for (i=0;i<VARBITBYTES(str)-VARBITBYTES(substr)+1;i++)
11651228
{
11661229
for (is=0;is<BITS_PER_BYTE;is++)
11671230
{
11681231
is_match= true;
1169-
p=VARBITS(arg)+i;
1232+
p=VARBITS(str)+i;
11701233
mask1=BITMASK >>is;
11711234
mask2= ~mask1;
11721235
for (s=VARBITS(substr);
@@ -1176,23 +1239,23 @@ bitposition(PG_FUNCTION_ARGS)
11761239
if (s==VARBITEND(substr)-1)
11771240
{
11781241
mask1 &=end_mask >>is;
1179-
if (p==VARBITEND(arg)-1)
1242+
if (p==VARBITEND(str)-1)
11801243
{
1181-
/* Check that there is enough ofarg left */
1182-
if (mask1& ~arg_mask)
1244+
/* Check that there is enough ofstr left */
1245+
if (mask1& ~str_mask)
11831246
{
11841247
is_match= false;
11851248
break;
11861249
}
1187-
mask1 &=arg_mask;
1250+
mask1 &=str_mask;
11881251
}
11891252
}
11901253
is_match= ((cmp ^*p)&mask1)==0;
11911254
if (!is_match)
11921255
break;
11931256
/* Move on to the next byte */
11941257
p++;
1195-
if (p==VARBITEND(arg))
1258+
if (p==VARBITEND(str))
11961259
{
11971260
mask2=end_mask << (BITS_PER_BYTE-is);
11981261
is_match=mask2==0;
@@ -1206,19 +1269,19 @@ bitposition(PG_FUNCTION_ARGS)
12061269
if (s==VARBITEND(substr)-1)
12071270
{
12081271
mask2 &=end_mask << (BITS_PER_BYTE-is);
1209-
if (p==VARBITEND(arg)-1)
1272+
if (p==VARBITEND(str)-1)
12101273
{
1211-
if (mask2& ~arg_mask)
1274+
if (mask2& ~str_mask)
12121275
{
12131276
is_match= false;
12141277
break;
12151278
}
1216-
mask2 &=arg_mask;
1279+
mask2 &=str_mask;
12171280
}
12181281
}
12191282
is_match= ((cmp ^*p)&mask2)==0;
12201283
}
1221-
/* Have we found a match */
1284+
/* Have we found a match? */
12221285
if (is_match)
12231286
PG_RETURN_INT32(i*BITS_PER_BYTE+is+1);
12241287
}

‎src/include/catalog/pg_proc.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: pg_proc.h,v 1.248 2002/07/31 01:49:13 momjian Exp $
10+
* $Id: pg_proc.h,v 1.249 2002/08/04 06:33:54 thomas Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -2236,9 +2236,9 @@ DATA(insert OID = 1681 ( lengthPGNSP PGUID 12 f f t f i 1 23 "1560"bitlengt
22362236
DESCR("bitstring length");
22372237
DATA(insertOID=1682 (octet_lengthPGNSPPGUID12fftfi123"1560"bitoctetlength-_null_ ));
22382238
DESCR("octet length");
2239-
DATA(insertOID=1683 (bitfromint4PGNSPPGUID12fftfi11560"23"bitfromint4-_null_ ));
2239+
DATA(insertOID=1683 (bitPGNSPPGUID12fftfi11560"23"bitfromint4-_null_ ));
22402240
DESCR("int4 to bitstring");
2241-
DATA(insertOID=1684 (bittoint4PGNSPPGUID12fftfi123"1560"bittoint4-_null_ ));
2241+
DATA(insertOID=1684 (int4PGNSPPGUID12fftfi123"1560"bittoint4-_null_ ));
22422242
DESCR("bitstring to int4");
22432243

22442244
DATA(insertOID=1685 (bitPGNSPPGUID12fftfi21560"1560 23"bit-_null_ ));
@@ -2873,6 +2873,11 @@ DESCR("substitutes regular expression");
28732873
DATA(insertOID=2074 (substringPGNSPPGUID14fftfi325"25 25 25""select substring($1, like_escape($2, $3))"-_null_ ));
28742874
DESCR("substitutes regular expression with escape argument");
28752875

2876+
DATA(insertOID=2075 (bitPGNSPPGUID12fftfi11560"20"bitfromint8-_null_ ));
2877+
DESCR("int8 to bitstring");
2878+
DATA(insertOID=2076 (int8PGNSPPGUID12fftfi120"1560"bittoint8-_null_ ));
2879+
DESCR("bitstring to int8");
2880+
28762881
DATA(insertOID=2090 (current_settingPGNSPPGUID12fftfs125"25"show_config_by_name-_null_ ));
28772882
DESCR("SHOW X as a function");
28782883
DATA(insertOID=2091 (set_configPGNSPPGUID12ffffv325"25 25 16"set_config_by_name-_null_ ));

‎src/include/utils/varbit.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $Id: varbit.h,v 1.14 2002/06/20 20:29:53 momjian Exp $
11+
* $Id: varbit.h,v 1.15 2002/08/04 06:33:56 thomas Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -88,6 +88,8 @@ extern Datum bitlength(PG_FUNCTION_ARGS);
8888
externDatumbitoctetlength(PG_FUNCTION_ARGS);
8989
externDatumbitfromint4(PG_FUNCTION_ARGS);
9090
externDatumbittoint4(PG_FUNCTION_ARGS);
91+
externDatumbitfromint8(PG_FUNCTION_ARGS);
92+
externDatumbittoint8(PG_FUNCTION_ARGS);
9193
externDatumbitposition(PG_FUNCTION_ARGS);
9294

9395
#endif

‎src/test/regress/expected/bit.out

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
--
77
CREATE TABLE BIT_TABLE(b BIT(11));
88
INSERT INTO BIT_TABLE VALUES (B'10'); -- too short
9-
ERROR:bit string length does not match typebit(11)
9+
ERROR:Bit string length2does not match typeBIT(11)
1010
INSERT INTO BIT_TABLE VALUES (B'00000000000');
1111
INSERT INTO BIT_TABLE VALUES (B'11011000000');
1212
INSERT INTO BIT_TABLE VALUES (B'01010101010');
1313
INSERT INTO BIT_TABLE VALUES (B'101011111010'); -- too long
14-
ERROR:bit string length does not match typebit(11)
14+
ERROR:Bit string length12does not match typeBIT(11)
1515
--INSERT INTO BIT_TABLE VALUES ('X554');
1616
--INSERT INTO BIT_TABLE VALUES ('X555');
1717
SELECT * FROM BIT_TABLE;
@@ -28,7 +28,7 @@ INSERT INTO VARBIT_TABLE VALUES (B'0');
2828
INSERT INTO VARBIT_TABLE VALUES (B'010101');
2929
INSERT INTO VARBIT_TABLE VALUES (B'01010101010');
3030
INSERT INTO VARBIT_TABLE VALUES (B'101011111010'); -- too long
31-
ERROR:bit string too long for typebit varying(11)
31+
ERROR:Bit string too long for typeBIT VARYING(11)
3232
--INSERT INTO VARBIT_TABLE VALUES ('X554');
3333
--INSERT INTO VARBIT_TABLE VALUES ('X555');
3434
SELECT * FROM VARBIT_TABLE;
@@ -212,11 +212,11 @@ SELECT a,a<<4 AS "a<<4",b,b>>2 AS "b>>2" FROM bit_table;
212212
DROP TABLE bit_table;
213213
-- The following should fail
214214
select B'001' & B'10';
215-
ERROR:cannot AND bit strings of different sizes
215+
ERROR:Cannot AND bit strings of different sizes
216216
select B'0111' | B'011';
217-
ERROR:cannot OR bit strings of different sizes
217+
ERROR:Cannot OR bit strings of different sizes
218218
select B'0010' # B'011101';
219-
ERROR:cannot XOR bit strings of different sizes
219+
ERROR:Cannot XOR bit strings of different sizes
220220
-- More position tests, checking all the boundary cases
221221
SELECT POSITION(B'1010' IN B'0000101'); -- 0
222222
position

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp