00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "postgres.h"
00018
00019 #include "access/htup_details.h"
00020 #include "libpq/pqformat.h"
00021 #include "nodes/nodeFuncs.h"
00022 #include "utils/array.h"
00023 #include "utils/varbit.h"
00024
00025 #define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
00026
00027 static VarBit *bit_catenate(VarBit *arg1, VarBit *arg2);
00028 static VarBit *bitsubstring(VarBit *arg, int32 s, int32 l,
00029 bool length_not_specified);
00030 static VarBit *bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl);
00031
00032
00033
00034
00035
00036 static int32
00037 anybit_typmodin(ArrayType *ta, const char *typename)
00038 {
00039 int32 typmod;
00040 int32 *tl;
00041 int n;
00042
00043 tl = ArrayGetIntegerTypmods(ta, &n);
00044
00045
00046
00047
00048
00049 if (n != 1)
00050 ereport(ERROR,
00051 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00052 errmsg("invalid type modifier")));
00053
00054 if (*tl < 1)
00055 ereport(ERROR,
00056 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00057 errmsg("length for type %s must be at least 1",
00058 typename)));
00059 if (*tl > (MaxAttrSize * BITS_PER_BYTE))
00060 ereport(ERROR,
00061 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00062 errmsg("length for type %s cannot exceed %d",
00063 typename, MaxAttrSize * BITS_PER_BYTE)));
00064
00065 typmod = *tl;
00066
00067 return typmod;
00068 }
00069
00070
00071
00072
00073 static char *
00074 anybit_typmodout(int32 typmod)
00075 {
00076 char *res = (char *) palloc(64);
00077
00078 if (typmod >= 0)
00079 snprintf(res, 64, "(%d)", typmod);
00080 else
00081 *res = '\0';
00082
00083 return res;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 Datum
00112 bit_in(PG_FUNCTION_ARGS)
00113 {
00114 char *input_string = PG_GETARG_CSTRING(0);
00115
00116 #ifdef NOT_USED
00117 Oid typelem = PG_GETARG_OID(1);
00118 #endif
00119 int32 atttypmod = PG_GETARG_INT32(2);
00120 VarBit *result;
00121 char *sp;
00122 bits8 *r;
00123 int len,
00124 bitlen,
00125 slen;
00126 bool bit_not_hex;
00127 int bc;
00128 bits8 x = 0;
00129
00130
00131 if (input_string[0] == 'b' || input_string[0] == 'B')
00132 {
00133 bit_not_hex = true;
00134 sp = input_string + 1;
00135 }
00136 else if (input_string[0] == 'x' || input_string[0] == 'X')
00137 {
00138 bit_not_hex = false;
00139 sp = input_string + 1;
00140 }
00141 else
00142 {
00143
00144
00145
00146
00147 bit_not_hex = true;
00148 sp = input_string;
00149 }
00150
00151 slen = strlen(sp);
00152
00153 if (bit_not_hex)
00154 bitlen = slen;
00155 else
00156 bitlen = slen * 4;
00157
00158
00159
00160
00161
00162 if (atttypmod <= 0)
00163 atttypmod = bitlen;
00164 else if (bitlen != atttypmod)
00165 ereport(ERROR,
00166 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
00167 errmsg("bit string length %d does not match type bit(%d)",
00168 bitlen, atttypmod)));
00169
00170 len = VARBITTOTALLEN(atttypmod);
00171
00172 result = (VarBit *) palloc0(len);
00173 SET_VARSIZE(result, len);
00174 VARBITLEN(result) = atttypmod;
00175
00176 r = VARBITS(result);
00177 if (bit_not_hex)
00178 {
00179
00180
00181 x = HIGHBIT;
00182 for (; *sp; sp++)
00183 {
00184 if (*sp == '1')
00185 *r |= x;
00186 else if (*sp != '0')
00187 ereport(ERROR,
00188 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00189 errmsg("\"%c\" is not a valid binary digit",
00190 *sp)));
00191
00192 x >>= 1;
00193 if (x == 0)
00194 {
00195 x = HIGHBIT;
00196 r++;
00197 }
00198 }
00199 }
00200 else
00201 {
00202
00203 for (bc = 0; *sp; sp++)
00204 {
00205 if (*sp >= '0' && *sp <= '9')
00206 x = (bits8) (*sp - '0');
00207 else if (*sp >= 'A' && *sp <= 'F')
00208 x = (bits8) (*sp - 'A') + 10;
00209 else if (*sp >= 'a' && *sp <= 'f')
00210 x = (bits8) (*sp - 'a') + 10;
00211 else
00212 ereport(ERROR,
00213 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00214 errmsg("\"%c\" is not a valid hexadecimal digit",
00215 *sp)));
00216
00217 if (bc)
00218 {
00219 *r++ |= x;
00220 bc = 0;
00221 }
00222 else
00223 {
00224 *r = x << 4;
00225 bc = 1;
00226 }
00227 }
00228 }
00229
00230 PG_RETURN_VARBIT_P(result);
00231 }
00232
00233
00234 Datum
00235 bit_out(PG_FUNCTION_ARGS)
00236 {
00237 #if 1
00238
00239 return varbit_out(fcinfo);
00240 #else
00241
00242
00243
00244
00245
00246 VarBit *s = PG_GETARG_VARBIT_P(0);
00247 char *result,
00248 *r;
00249 bits8 *sp;
00250 int i,
00251 len,
00252 bitlen;
00253
00254 bitlen = VARBITLEN(s);
00255 len = (bitlen + 3) / 4;
00256 result = (char *) palloc(len + 2);
00257 sp = VARBITS(s);
00258 r = result;
00259 *r++ = 'X';
00260
00261 for (i = 0; i < len; i += 2, sp++)
00262 {
00263 *r++ = HEXDIG((*sp) >> 4);
00264 *r++ = HEXDIG((*sp) & 0xF);
00265 }
00266
00267
00268
00269
00270
00271 if (i > len)
00272 r--;
00273 *r = '\0';
00274
00275 PG_RETURN_CSTRING(result);
00276 #endif
00277 }
00278
00279
00280
00281
00282 Datum
00283 bit_recv(PG_FUNCTION_ARGS)
00284 {
00285 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00286
00287 #ifdef NOT_USED
00288 Oid typelem = PG_GETARG_OID(1);
00289 #endif
00290 int32 atttypmod = PG_GETARG_INT32(2);
00291 VarBit *result;
00292 int len,
00293 bitlen;
00294 int ipad;
00295 bits8 mask;
00296
00297 bitlen = pq_getmsgint(buf, sizeof(int32));
00298 if (bitlen < 0)
00299 ereport(ERROR,
00300 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
00301 errmsg("invalid length in external bit string")));
00302
00303
00304
00305
00306
00307 if (atttypmod > 0 && bitlen != atttypmod)
00308 ereport(ERROR,
00309 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
00310 errmsg("bit string length %d does not match type bit(%d)",
00311 bitlen, atttypmod)));
00312
00313 len = VARBITTOTALLEN(bitlen);
00314 result = (VarBit *) palloc(len);
00315 SET_VARSIZE(result, len);
00316 VARBITLEN(result) = bitlen;
00317
00318 pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));
00319
00320
00321 ipad = VARBITPAD(result);
00322 if (ipad > 0)
00323 {
00324 mask = BITMASK << ipad;
00325 *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
00326 }
00327
00328 PG_RETURN_VARBIT_P(result);
00329 }
00330
00331
00332
00333
00334 Datum
00335 bit_send(PG_FUNCTION_ARGS)
00336 {
00337
00338 return varbit_send(fcinfo);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349 Datum
00350 bit(PG_FUNCTION_ARGS)
00351 {
00352 VarBit *arg = PG_GETARG_VARBIT_P(0);
00353 int32 len = PG_GETARG_INT32(1);
00354 bool isExplicit = PG_GETARG_BOOL(2);
00355 VarBit *result;
00356 int rlen;
00357 int ipad;
00358 bits8 mask;
00359
00360
00361 if (len <= 0 || len == VARBITLEN(arg))
00362 PG_RETURN_VARBIT_P(arg);
00363
00364 if (!isExplicit)
00365 ereport(ERROR,
00366 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
00367 errmsg("bit string length %d does not match type bit(%d)",
00368 VARBITLEN(arg), len)));
00369
00370 rlen = VARBITTOTALLEN(len);
00371
00372 result = (VarBit *) palloc0(rlen);
00373 SET_VARSIZE(result, rlen);
00374 VARBITLEN(result) = len;
00375
00376 memcpy(VARBITS(result), VARBITS(arg),
00377 Min(VARBITBYTES(result), VARBITBYTES(arg)));
00378
00379
00380
00381
00382
00383
00384 ipad = VARBITPAD(result);
00385 if (ipad > 0)
00386 {
00387 mask = BITMASK << ipad;
00388 *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
00389 }
00390
00391 PG_RETURN_VARBIT_P(result);
00392 }
00393
00394 Datum
00395 bittypmodin(PG_FUNCTION_ARGS)
00396 {
00397 ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
00398
00399 PG_RETURN_INT32(anybit_typmodin(ta, "bit"));
00400 }
00401
00402 Datum
00403 bittypmodout(PG_FUNCTION_ARGS)
00404 {
00405 int32 typmod = PG_GETARG_INT32(0);
00406
00407 PG_RETURN_CSTRING(anybit_typmodout(typmod));
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417 Datum
00418 varbit_in(PG_FUNCTION_ARGS)
00419 {
00420 char *input_string = PG_GETARG_CSTRING(0);
00421
00422 #ifdef NOT_USED
00423 Oid typelem = PG_GETARG_OID(1);
00424 #endif
00425 int32 atttypmod = PG_GETARG_INT32(2);
00426 VarBit *result;
00427 char *sp;
00428 bits8 *r;
00429 int len,
00430 bitlen,
00431 slen;
00432 bool bit_not_hex;
00433 int bc;
00434 bits8 x = 0;
00435
00436
00437 if (input_string[0] == 'b' || input_string[0] == 'B')
00438 {
00439 bit_not_hex = true;
00440 sp = input_string + 1;
00441 }
00442 else if (input_string[0] == 'x' || input_string[0] == 'X')
00443 {
00444 bit_not_hex = false;
00445 sp = input_string + 1;
00446 }
00447 else
00448 {
00449 bit_not_hex = true;
00450 sp = input_string;
00451 }
00452
00453 slen = strlen(sp);
00454
00455 if (bit_not_hex)
00456 bitlen = slen;
00457 else
00458 bitlen = slen * 4;
00459
00460
00461
00462
00463
00464 if (atttypmod <= 0)
00465 atttypmod = bitlen;
00466 else if (bitlen > atttypmod)
00467 ereport(ERROR,
00468 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
00469 errmsg("bit string too long for type bit varying(%d)",
00470 atttypmod)));
00471
00472 len = VARBITTOTALLEN(bitlen);
00473
00474 result = (VarBit *) palloc0(len);
00475 SET_VARSIZE(result, len);
00476 VARBITLEN(result) = Min(bitlen, atttypmod);
00477
00478 r = VARBITS(result);
00479 if (bit_not_hex)
00480 {
00481
00482
00483 x = HIGHBIT;
00484 for (; *sp; sp++)
00485 {
00486 if (*sp == '1')
00487 *r |= x;
00488 else if (*sp != '0')
00489 ereport(ERROR,
00490 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00491 errmsg("\"%c\" is not a valid binary digit",
00492 *sp)));
00493
00494 x >>= 1;
00495 if (x == 0)
00496 {
00497 x = HIGHBIT;
00498 r++;
00499 }
00500 }
00501 }
00502 else
00503 {
00504
00505 for (bc = 0; *sp; sp++)
00506 {
00507 if (*sp >= '0' && *sp <= '9')
00508 x = (bits8) (*sp - '0');
00509 else if (*sp >= 'A' && *sp <= 'F')
00510 x = (bits8) (*sp - 'A') + 10;
00511 else if (*sp >= 'a' && *sp <= 'f')
00512 x = (bits8) (*sp - 'a') + 10;
00513 else
00514 ereport(ERROR,
00515 (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
00516 errmsg("\"%c\" is not a valid hexadecimal digit",
00517 *sp)));
00518
00519 if (bc)
00520 {
00521 *r++ |= x;
00522 bc = 0;
00523 }
00524 else
00525 {
00526 *r = x << 4;
00527 bc = 1;
00528 }
00529 }
00530 }
00531
00532 PG_RETURN_VARBIT_P(result);
00533 }
00534
00535
00536
00537
00538
00539 Datum
00540 varbit_out(PG_FUNCTION_ARGS)
00541 {
00542 VarBit *s = PG_GETARG_VARBIT_P(0);
00543 char *result,
00544 *r;
00545 bits8 *sp;
00546 bits8 x;
00547 int i,
00548 k,
00549 len;
00550
00551 len = VARBITLEN(s);
00552 result = (char *) palloc(len + 1);
00553 sp = VARBITS(s);
00554 r = result;
00555 for (i = 0; i <= len - BITS_PER_BYTE; i += BITS_PER_BYTE, sp++)
00556 {
00557
00558 x = *sp;
00559 for (k = 0; k < BITS_PER_BYTE; k++)
00560 {
00561 *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
00562 x <<= 1;
00563 }
00564 }
00565 if (i < len)
00566 {
00567
00568 x = *sp;
00569 for (k = i; k < len; k++)
00570 {
00571 *r++ = IS_HIGHBIT_SET(x) ? '1' : '0';
00572 x <<= 1;
00573 }
00574 }
00575 *r = '\0';
00576
00577 PG_RETURN_CSTRING(result);
00578 }
00579
00580
00581
00582
00583
00584
00585 Datum
00586 varbit_recv(PG_FUNCTION_ARGS)
00587 {
00588 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00589
00590 #ifdef NOT_USED
00591 Oid typelem = PG_GETARG_OID(1);
00592 #endif
00593 int32 atttypmod = PG_GETARG_INT32(2);
00594 VarBit *result;
00595 int len,
00596 bitlen;
00597 int ipad;
00598 bits8 mask;
00599
00600 bitlen = pq_getmsgint(buf, sizeof(int32));
00601 if (bitlen < 0)
00602 ereport(ERROR,
00603 (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
00604 errmsg("invalid length in external bit string")));
00605
00606
00607
00608
00609
00610 if (atttypmod > 0 && bitlen > atttypmod)
00611 ereport(ERROR,
00612 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
00613 errmsg("bit string too long for type bit varying(%d)",
00614 atttypmod)));
00615
00616 len = VARBITTOTALLEN(bitlen);
00617 result = (VarBit *) palloc(len);
00618 SET_VARSIZE(result, len);
00619 VARBITLEN(result) = bitlen;
00620
00621 pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));
00622
00623
00624 ipad = VARBITPAD(result);
00625 if (ipad > 0)
00626 {
00627 mask = BITMASK << ipad;
00628 *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
00629 }
00630
00631 PG_RETURN_VARBIT_P(result);
00632 }
00633
00634
00635
00636
00637 Datum
00638 varbit_send(PG_FUNCTION_ARGS)
00639 {
00640 VarBit *s = PG_GETARG_VARBIT_P(0);
00641 StringInfoData buf;
00642
00643 pq_begintypsend(&buf);
00644 pq_sendint(&buf, VARBITLEN(s), sizeof(int32));
00645 pq_sendbytes(&buf, (char *) VARBITS(s), VARBITBYTES(s));
00646 PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
00647 }
00648
00649
00650
00651
00652
00653
00654
00655 Datum
00656 varbit_transform(PG_FUNCTION_ARGS)
00657 {
00658 FuncExpr *expr = (FuncExpr *) PG_GETARG_POINTER(0);
00659 Node *ret = NULL;
00660 Node *typmod;
00661
00662 Assert(IsA(expr, FuncExpr));
00663 Assert(list_length(expr->args) >= 2);
00664
00665 typmod = (Node *) lsecond(expr->args);
00666
00667 if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull)
00668 {
00669 Node *source = (Node *) linitial(expr->args);
00670 int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
00671 int32 old_max = exprTypmod(source);
00672 int32 new_max = new_typmod;
00673
00674
00675 if (new_max <= 0 || (old_max > 0 && old_max <= new_max))
00676 ret = relabel_to_typmod(source, new_typmod);
00677 }
00678
00679 PG_RETURN_POINTER(ret);
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690 Datum
00691 varbit(PG_FUNCTION_ARGS)
00692 {
00693 VarBit *arg = PG_GETARG_VARBIT_P(0);
00694 int32 len = PG_GETARG_INT32(1);
00695 bool isExplicit = PG_GETARG_BOOL(2);
00696 VarBit *result;
00697 int rlen;
00698 int ipad;
00699 bits8 mask;
00700
00701
00702 if (len <= 0 || len >= VARBITLEN(arg))
00703 PG_RETURN_VARBIT_P(arg);
00704
00705 if (!isExplicit)
00706 ereport(ERROR,
00707 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
00708 errmsg("bit string too long for type bit varying(%d)",
00709 len)));
00710
00711 rlen = VARBITTOTALLEN(len);
00712 result = (VarBit *) palloc(rlen);
00713 SET_VARSIZE(result, rlen);
00714 VARBITLEN(result) = len;
00715
00716 memcpy(VARBITS(result), VARBITS(arg), VARBITBYTES(result));
00717
00718
00719 ipad = VARBITPAD(result);
00720 if (ipad > 0)
00721 {
00722 mask = BITMASK << ipad;
00723 *(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
00724 }
00725
00726 PG_RETURN_VARBIT_P(result);
00727 }
00728
00729 Datum
00730 varbittypmodin(PG_FUNCTION_ARGS)
00731 {
00732 ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
00733
00734 PG_RETURN_INT32(anybit_typmodin(ta, "varbit"));
00735 }
00736
00737 Datum
00738 varbittypmodout(PG_FUNCTION_ARGS)
00739 {
00740 int32 typmod = PG_GETARG_INT32(0);
00741
00742 PG_RETURN_CSTRING(anybit_typmodout(typmod));
00743 }
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 static int32
00774 bit_cmp(VarBit *arg1, VarBit *arg2)
00775 {
00776 int bitlen1,
00777 bytelen1,
00778 bitlen2,
00779 bytelen2;
00780 int32 cmp;
00781
00782 bytelen1 = VARBITBYTES(arg1);
00783 bytelen2 = VARBITBYTES(arg2);
00784
00785 cmp = memcmp(VARBITS(arg1), VARBITS(arg2), Min(bytelen1, bytelen2));
00786 if (cmp == 0)
00787 {
00788 bitlen1 = VARBITLEN(arg1);
00789 bitlen2 = VARBITLEN(arg2);
00790 if (bitlen1 != bitlen2)
00791 cmp = (bitlen1 < bitlen2) ? -1 : 1;
00792 }
00793 return cmp;
00794 }
00795
00796 Datum
00797 biteq(PG_FUNCTION_ARGS)
00798 {
00799 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00800 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00801 bool result;
00802 int bitlen1,
00803 bitlen2;
00804
00805 bitlen1 = VARBITLEN(arg1);
00806 bitlen2 = VARBITLEN(arg2);
00807
00808
00809 if (bitlen1 != bitlen2)
00810 result = false;
00811 else
00812 result = (bit_cmp(arg1, arg2) == 0);
00813
00814 PG_FREE_IF_COPY(arg1, 0);
00815 PG_FREE_IF_COPY(arg2, 1);
00816
00817 PG_RETURN_BOOL(result);
00818 }
00819
00820 Datum
00821 bitne(PG_FUNCTION_ARGS)
00822 {
00823 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00824 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00825 bool result;
00826 int bitlen1,
00827 bitlen2;
00828
00829 bitlen1 = VARBITLEN(arg1);
00830 bitlen2 = VARBITLEN(arg2);
00831
00832
00833 if (bitlen1 != bitlen2)
00834 result = true;
00835 else
00836 result = (bit_cmp(arg1, arg2) != 0);
00837
00838 PG_FREE_IF_COPY(arg1, 0);
00839 PG_FREE_IF_COPY(arg2, 1);
00840
00841 PG_RETURN_BOOL(result);
00842 }
00843
00844 Datum
00845 bitlt(PG_FUNCTION_ARGS)
00846 {
00847 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00848 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00849 bool result;
00850
00851 result = (bit_cmp(arg1, arg2) < 0);
00852
00853 PG_FREE_IF_COPY(arg1, 0);
00854 PG_FREE_IF_COPY(arg2, 1);
00855
00856 PG_RETURN_BOOL(result);
00857 }
00858
00859 Datum
00860 bitle(PG_FUNCTION_ARGS)
00861 {
00862 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00863 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00864 bool result;
00865
00866 result = (bit_cmp(arg1, arg2) <= 0);
00867
00868 PG_FREE_IF_COPY(arg1, 0);
00869 PG_FREE_IF_COPY(arg2, 1);
00870
00871 PG_RETURN_BOOL(result);
00872 }
00873
00874 Datum
00875 bitgt(PG_FUNCTION_ARGS)
00876 {
00877 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00878 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00879 bool result;
00880
00881 result = (bit_cmp(arg1, arg2) > 0);
00882
00883 PG_FREE_IF_COPY(arg1, 0);
00884 PG_FREE_IF_COPY(arg2, 1);
00885
00886 PG_RETURN_BOOL(result);
00887 }
00888
00889 Datum
00890 bitge(PG_FUNCTION_ARGS)
00891 {
00892 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00893 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00894 bool result;
00895
00896 result = (bit_cmp(arg1, arg2) >= 0);
00897
00898 PG_FREE_IF_COPY(arg1, 0);
00899 PG_FREE_IF_COPY(arg2, 1);
00900
00901 PG_RETURN_BOOL(result);
00902 }
00903
00904 Datum
00905 bitcmp(PG_FUNCTION_ARGS)
00906 {
00907 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00908 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00909 int32 result;
00910
00911 result = bit_cmp(arg1, arg2);
00912
00913 PG_FREE_IF_COPY(arg1, 0);
00914 PG_FREE_IF_COPY(arg2, 1);
00915
00916 PG_RETURN_INT32(result);
00917 }
00918
00919
00920
00921
00922
00923 Datum
00924 bitcat(PG_FUNCTION_ARGS)
00925 {
00926 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
00927 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
00928
00929 PG_RETURN_VARBIT_P(bit_catenate(arg1, arg2));
00930 }
00931
00932 static VarBit *
00933 bit_catenate(VarBit *arg1, VarBit *arg2)
00934 {
00935 VarBit *result;
00936 int bitlen1,
00937 bitlen2,
00938 bytelen,
00939 bit1pad,
00940 bit2shift;
00941 bits8 *pr,
00942 *pa;
00943
00944 bitlen1 = VARBITLEN(arg1);
00945 bitlen2 = VARBITLEN(arg2);
00946
00947 bytelen = VARBITTOTALLEN(bitlen1 + bitlen2);
00948
00949 result = (VarBit *) palloc(bytelen);
00950 SET_VARSIZE(result, bytelen);
00951 VARBITLEN(result) = bitlen1 + bitlen2;
00952
00953
00954 memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
00955
00956
00957 bit1pad = VARBITPAD(arg1);
00958 if (bit1pad == 0)
00959 {
00960 memcpy(VARBITS(result) + VARBITBYTES(arg1), VARBITS(arg2),
00961 VARBITBYTES(arg2));
00962 }
00963 else if (bitlen2 > 0)
00964 {
00965
00966 bit2shift = BITS_PER_BYTE - bit1pad;
00967 pr = VARBITS(result) + VARBITBYTES(arg1) - 1;
00968 for (pa = VARBITS(arg2); pa < VARBITEND(arg2); pa++)
00969 {
00970 *pr |= ((*pa >> bit2shift) & BITMASK);
00971 pr++;
00972 if (pr < VARBITEND(result))
00973 *pr = (*pa << bit1pad) & BITMASK;
00974 }
00975 }
00976
00977 return result;
00978 }
00979
00980
00981
00982
00983
00984
00985
00986 Datum
00987 bitsubstr(PG_FUNCTION_ARGS)
00988 {
00989 PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
00990 PG_GETARG_INT32(1),
00991 PG_GETARG_INT32(2),
00992 false));
00993 }
00994
00995 Datum
00996 bitsubstr_no_len(PG_FUNCTION_ARGS)
00997 {
00998 PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
00999 PG_GETARG_INT32(1),
01000 -1, true));
01001 }
01002
01003 static VarBit *
01004 bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
01005 {
01006 VarBit *result;
01007 int bitlen,
01008 rbitlen,
01009 len,
01010 ipad = 0,
01011 ishift,
01012 i;
01013 int e,
01014 s1,
01015 e1;
01016 bits8 mask,
01017 *r,
01018 *ps;
01019
01020 bitlen = VARBITLEN(arg);
01021 s1 = Max(s, 1);
01022
01023 if (length_not_specified)
01024 {
01025 e1 = bitlen + 1;
01026 }
01027 else
01028 {
01029 e = s + l;
01030
01031
01032
01033
01034
01035 if (e < s)
01036 ereport(ERROR,
01037 (errcode(ERRCODE_SUBSTRING_ERROR),
01038 errmsg("negative substring length not allowed")));
01039 e1 = Min(e, bitlen + 1);
01040 }
01041 if (s1 > bitlen || e1 <= s1)
01042 {
01043
01044 len = VARBITTOTALLEN(0);
01045 result = (VarBit *) palloc(len);
01046 SET_VARSIZE(result, len);
01047 VARBITLEN(result) = 0;
01048 }
01049 else
01050 {
01051
01052
01053
01054
01055 rbitlen = e1 - s1;
01056 len = VARBITTOTALLEN(rbitlen);
01057 result = (VarBit *) palloc(len);
01058 SET_VARSIZE(result, len);
01059 VARBITLEN(result) = rbitlen;
01060 len -= VARHDRSZ + VARBITHDRSZ;
01061
01062 if ((s1 - 1) % BITS_PER_BYTE == 0)
01063 {
01064
01065 memcpy(VARBITS(result), VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE,
01066 len);
01067 }
01068 else
01069 {
01070
01071 ishift = (s1 - 1) % BITS_PER_BYTE;
01072 r = VARBITS(result);
01073 ps = VARBITS(arg) + (s1 - 1) / BITS_PER_BYTE;
01074 for (i = 0; i < len; i++)
01075 {
01076 *r = (*ps << ishift) & BITMASK;
01077 if ((++ps) < VARBITEND(arg))
01078 *r |= *ps >> (BITS_PER_BYTE - ishift);
01079 r++;
01080 }
01081 }
01082
01083 ipad = VARBITPAD(result);
01084 if (ipad > 0)
01085 {
01086 mask = BITMASK << ipad;
01087 *(VARBITS(result) + len - 1) &= mask;
01088 }
01089 }
01090
01091 return result;
01092 }
01093
01094
01095
01096
01097
01098
01099
01100
01101 Datum
01102 bitoverlay(PG_FUNCTION_ARGS)
01103 {
01104 VarBit *t1 = PG_GETARG_VARBIT_P(0);
01105 VarBit *t2 = PG_GETARG_VARBIT_P(1);
01106 int sp = PG_GETARG_INT32(2);
01107 int sl = PG_GETARG_INT32(3);
01108
01109 PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
01110 }
01111
01112 Datum
01113 bitoverlay_no_len(PG_FUNCTION_ARGS)
01114 {
01115 VarBit *t1 = PG_GETARG_VARBIT_P(0);
01116 VarBit *t2 = PG_GETARG_VARBIT_P(1);
01117 int sp = PG_GETARG_INT32(2);
01118 int sl;
01119
01120 sl = VARBITLEN(t2);
01121 PG_RETURN_VARBIT_P(bit_overlay(t1, t2, sp, sl));
01122 }
01123
01124 static VarBit *
01125 bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl)
01126 {
01127 VarBit *result;
01128 VarBit *s1;
01129 VarBit *s2;
01130 int sp_pl_sl;
01131
01132
01133
01134
01135
01136
01137 if (sp <= 0)
01138 ereport(ERROR,
01139 (errcode(ERRCODE_SUBSTRING_ERROR),
01140 errmsg("negative substring length not allowed")));
01141 sp_pl_sl = sp + sl;
01142 if (sp_pl_sl <= sl)
01143 ereport(ERROR,
01144 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01145 errmsg("integer out of range")));
01146
01147 s1 = bitsubstring(t1, 1, sp - 1, false);
01148 s2 = bitsubstring(t1, sp_pl_sl, -1, true);
01149 result = bit_catenate(s1, t2);
01150 result = bit_catenate(result, s2);
01151
01152 return result;
01153 }
01154
01155
01156
01157
01158
01159 Datum
01160 bitlength(PG_FUNCTION_ARGS)
01161 {
01162 VarBit *arg = PG_GETARG_VARBIT_P(0);
01163
01164 PG_RETURN_INT32(VARBITLEN(arg));
01165 }
01166
01167 Datum
01168 bitoctetlength(PG_FUNCTION_ARGS)
01169 {
01170 VarBit *arg = PG_GETARG_VARBIT_P(0);
01171
01172 PG_RETURN_INT32(VARBITBYTES(arg));
01173 }
01174
01175
01176
01177
01178
01179 Datum
01180 bit_and(PG_FUNCTION_ARGS)
01181 {
01182 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
01183 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
01184 VarBit *result;
01185 int len,
01186 bitlen1,
01187 bitlen2,
01188 i;
01189 bits8 *p1,
01190 *p2,
01191 *r;
01192
01193 bitlen1 = VARBITLEN(arg1);
01194 bitlen2 = VARBITLEN(arg2);
01195 if (bitlen1 != bitlen2)
01196 ereport(ERROR,
01197 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
01198 errmsg("cannot AND bit strings of different sizes")));
01199
01200 len = VARSIZE(arg1);
01201 result = (VarBit *) palloc(len);
01202 SET_VARSIZE(result, len);
01203 VARBITLEN(result) = bitlen1;
01204
01205 p1 = VARBITS(arg1);
01206 p2 = VARBITS(arg2);
01207 r = VARBITS(result);
01208 for (i = 0; i < VARBITBYTES(arg1); i++)
01209 *r++ = *p1++ & *p2++;
01210
01211
01212
01213 PG_RETURN_VARBIT_P(result);
01214 }
01215
01216
01217
01218
01219
01220 Datum
01221 bit_or(PG_FUNCTION_ARGS)
01222 {
01223 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
01224 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
01225 VarBit *result;
01226 int len,
01227 bitlen1,
01228 bitlen2,
01229 i;
01230 bits8 *p1,
01231 *p2,
01232 *r;
01233 bits8 mask;
01234
01235 bitlen1 = VARBITLEN(arg1);
01236 bitlen2 = VARBITLEN(arg2);
01237 if (bitlen1 != bitlen2)
01238 ereport(ERROR,
01239 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
01240 errmsg("cannot OR bit strings of different sizes")));
01241 len = VARSIZE(arg1);
01242 result = (VarBit *) palloc(len);
01243 SET_VARSIZE(result, len);
01244 VARBITLEN(result) = bitlen1;
01245
01246 p1 = VARBITS(arg1);
01247 p2 = VARBITS(arg2);
01248 r = VARBITS(result);
01249 for (i = 0; i < VARBITBYTES(arg1); i++)
01250 *r++ = *p1++ | *p2++;
01251
01252
01253 mask = BITMASK << VARBITPAD(result);
01254 if (mask)
01255 {
01256 r--;
01257 *r &= mask;
01258 }
01259
01260 PG_RETURN_VARBIT_P(result);
01261 }
01262
01263
01264
01265
01266
01267 Datum
01268 bitxor(PG_FUNCTION_ARGS)
01269 {
01270 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
01271 VarBit *arg2 = PG_GETARG_VARBIT_P(1);
01272 VarBit *result;
01273 int len,
01274 bitlen1,
01275 bitlen2,
01276 i;
01277 bits8 *p1,
01278 *p2,
01279 *r;
01280 bits8 mask;
01281
01282 bitlen1 = VARBITLEN(arg1);
01283 bitlen2 = VARBITLEN(arg2);
01284 if (bitlen1 != bitlen2)
01285 ereport(ERROR,
01286 (errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
01287 errmsg("cannot XOR bit strings of different sizes")));
01288
01289 len = VARSIZE(arg1);
01290 result = (VarBit *) palloc(len);
01291 SET_VARSIZE(result, len);
01292 VARBITLEN(result) = bitlen1;
01293
01294 p1 = VARBITS(arg1);
01295 p2 = VARBITS(arg2);
01296 r = VARBITS(result);
01297 for (i = 0; i < VARBITBYTES(arg1); i++)
01298 *r++ = *p1++ ^ *p2++;
01299
01300
01301 mask = BITMASK << VARBITPAD(result);
01302 if (mask)
01303 {
01304 r--;
01305 *r &= mask;
01306 }
01307
01308 PG_RETURN_VARBIT_P(result);
01309 }
01310
01311
01312
01313
01314
01315 Datum
01316 bitnot(PG_FUNCTION_ARGS)
01317 {
01318 VarBit *arg = PG_GETARG_VARBIT_P(0);
01319 VarBit *result;
01320 bits8 *p,
01321 *r;
01322 bits8 mask;
01323
01324 result = (VarBit *) palloc(VARSIZE(arg));
01325 SET_VARSIZE(result, VARSIZE(arg));
01326 VARBITLEN(result) = VARBITLEN(arg);
01327
01328 p = VARBITS(arg);
01329 r = VARBITS(result);
01330 for (; p < VARBITEND(arg); p++)
01331 *r++ = ~*p;
01332
01333
01334 mask = BITMASK << VARBITPAD(result);
01335 if (mask)
01336 {
01337 r--;
01338 *r &= mask;
01339 }
01340
01341 PG_RETURN_VARBIT_P(result);
01342 }
01343
01344
01345
01346
01347
01348 Datum
01349 bitshiftleft(PG_FUNCTION_ARGS)
01350 {
01351 VarBit *arg = PG_GETARG_VARBIT_P(0);
01352 int32 shft = PG_GETARG_INT32(1);
01353 VarBit *result;
01354 int byte_shift,
01355 ishift,
01356 len;
01357 bits8 *p,
01358 *r;
01359
01360
01361 if (shft < 0)
01362 PG_RETURN_DATUM(DirectFunctionCall2(bitshiftright,
01363 VarBitPGetDatum(arg),
01364 Int32GetDatum(-shft)));
01365
01366 result = (VarBit *) palloc(VARSIZE(arg));
01367 SET_VARSIZE(result, VARSIZE(arg));
01368 VARBITLEN(result) = VARBITLEN(arg);
01369 r = VARBITS(result);
01370
01371
01372 if (shft >= VARBITLEN(arg))
01373 {
01374 MemSet(r, 0, VARBITBYTES(arg));
01375 PG_RETURN_VARBIT_P(result);
01376 }
01377
01378 byte_shift = shft / BITS_PER_BYTE;
01379 ishift = shft % BITS_PER_BYTE;
01380 p = VARBITS(arg) + byte_shift;
01381
01382 if (ishift == 0)
01383 {
01384
01385 len = VARBITBYTES(arg) - byte_shift;
01386 memcpy(r, p, len);
01387 MemSet(r + len, 0, byte_shift);
01388 }
01389 else
01390 {
01391 for (; p < VARBITEND(arg); r++)
01392 {
01393 *r = *p << ishift;
01394 if ((++p) < VARBITEND(arg))
01395 *r |= *p >> (BITS_PER_BYTE - ishift);
01396 }
01397 for (; r < VARBITEND(result); r++)
01398 *r = 0;
01399 }
01400
01401 PG_RETURN_VARBIT_P(result);
01402 }
01403
01404
01405
01406
01407
01408 Datum
01409 bitshiftright(PG_FUNCTION_ARGS)
01410 {
01411 VarBit *arg = PG_GETARG_VARBIT_P(0);
01412 int32 shft = PG_GETARG_INT32(1);
01413 VarBit *result;
01414 int byte_shift,
01415 ishift,
01416 len;
01417 bits8 *p,
01418 *r;
01419
01420
01421 if (shft < 0)
01422 PG_RETURN_DATUM(DirectFunctionCall2(bitshiftleft,
01423 VarBitPGetDatum(arg),
01424 Int32GetDatum(-shft)));
01425
01426 result = (VarBit *) palloc(VARSIZE(arg));
01427 SET_VARSIZE(result, VARSIZE(arg));
01428 VARBITLEN(result) = VARBITLEN(arg);
01429 r = VARBITS(result);
01430
01431
01432 if (shft >= VARBITLEN(arg))
01433 {
01434 MemSet(r, 0, VARBITBYTES(arg));
01435 PG_RETURN_VARBIT_P(result);
01436 }
01437
01438 byte_shift = shft / BITS_PER_BYTE;
01439 ishift = shft % BITS_PER_BYTE;
01440 p = VARBITS(arg);
01441
01442
01443 MemSet(r, 0, byte_shift);
01444 r += byte_shift;
01445
01446 if (ishift == 0)
01447 {
01448
01449 len = VARBITBYTES(arg) - byte_shift;
01450 memcpy(r, p, len);
01451 }
01452 else
01453 {
01454 if (r < VARBITEND(result))
01455 *r = 0;
01456 for (; r < VARBITEND(result); p++)
01457 {
01458 *r |= *p >> ishift;
01459 if ((++r) < VARBITEND(result))
01460 *r = (*p << (BITS_PER_BYTE - ishift)) & BITMASK;
01461 }
01462 }
01463
01464 PG_RETURN_VARBIT_P(result);
01465 }
01466
01467
01468
01469
01470
01471 Datum
01472 bitfromint4(PG_FUNCTION_ARGS)
01473 {
01474 int32 a = PG_GETARG_INT32(0);
01475 int32 typmod = PG_GETARG_INT32(1);
01476 VarBit *result;
01477 bits8 *r;
01478 int rlen;
01479 int destbitsleft,
01480 srcbitsleft;
01481
01482 if (typmod <= 0)
01483 typmod = 1;
01484
01485 rlen = VARBITTOTALLEN(typmod);
01486 result = (VarBit *) palloc(rlen);
01487 SET_VARSIZE(result, rlen);
01488 VARBITLEN(result) = typmod;
01489
01490 r = VARBITS(result);
01491 destbitsleft = typmod;
01492 srcbitsleft = 32;
01493
01494 srcbitsleft = Min(srcbitsleft, destbitsleft);
01495
01496 while (destbitsleft >= srcbitsleft + 8)
01497 {
01498 *r++ = (bits8) ((a < 0) ? BITMASK : 0);
01499 destbitsleft -= 8;
01500 }
01501
01502 if (destbitsleft > srcbitsleft)
01503 {
01504 int val = (int) (a >> (destbitsleft - 8));
01505
01506
01507 if (a < 0)
01508 val |= (-1) << (srcbitsleft + 8 - destbitsleft);
01509 *r++ = (bits8) (val & BITMASK);
01510 destbitsleft -= 8;
01511 }
01512
01513
01514 while (destbitsleft >= 8)
01515 {
01516 *r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
01517 destbitsleft -= 8;
01518 }
01519
01520 if (destbitsleft > 0)
01521 *r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
01522
01523 PG_RETURN_VARBIT_P(result);
01524 }
01525
01526 Datum
01527 bittoint4(PG_FUNCTION_ARGS)
01528 {
01529 VarBit *arg = PG_GETARG_VARBIT_P(0);
01530 uint32 result;
01531 bits8 *r;
01532
01533
01534 if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
01535 ereport(ERROR,
01536 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01537 errmsg("integer out of range")));
01538
01539 result = 0;
01540 for (r = VARBITS(arg); r < VARBITEND(arg); r++)
01541 {
01542 result <<= BITS_PER_BYTE;
01543 result |= *r;
01544 }
01545
01546 result >>= VARBITPAD(arg);
01547
01548 PG_RETURN_INT32(result);
01549 }
01550
01551 Datum
01552 bitfromint8(PG_FUNCTION_ARGS)
01553 {
01554 int64 a = PG_GETARG_INT64(0);
01555 int32 typmod = PG_GETARG_INT32(1);
01556 VarBit *result;
01557 bits8 *r;
01558 int rlen;
01559 int destbitsleft,
01560 srcbitsleft;
01561
01562 if (typmod <= 0)
01563 typmod = 1;
01564
01565 rlen = VARBITTOTALLEN(typmod);
01566 result = (VarBit *) palloc(rlen);
01567 SET_VARSIZE(result, rlen);
01568 VARBITLEN(result) = typmod;
01569
01570 r = VARBITS(result);
01571 destbitsleft = typmod;
01572 srcbitsleft = 64;
01573
01574 srcbitsleft = Min(srcbitsleft, destbitsleft);
01575
01576 while (destbitsleft >= srcbitsleft + 8)
01577 {
01578 *r++ = (bits8) ((a < 0) ? BITMASK : 0);
01579 destbitsleft -= 8;
01580 }
01581
01582 if (destbitsleft > srcbitsleft)
01583 {
01584 int val = (int) (a >> (destbitsleft - 8));
01585
01586
01587 if (a < 0)
01588 val |= (-1) << (srcbitsleft + 8 - destbitsleft);
01589 *r++ = (bits8) (val & BITMASK);
01590 destbitsleft -= 8;
01591 }
01592
01593
01594 while (destbitsleft >= 8)
01595 {
01596 *r++ = (bits8) ((a >> (destbitsleft - 8)) & BITMASK);
01597 destbitsleft -= 8;
01598 }
01599
01600 if (destbitsleft > 0)
01601 *r = (bits8) ((a << (8 - destbitsleft)) & BITMASK);
01602
01603 PG_RETURN_VARBIT_P(result);
01604 }
01605
01606 Datum
01607 bittoint8(PG_FUNCTION_ARGS)
01608 {
01609 VarBit *arg = PG_GETARG_VARBIT_P(0);
01610 uint64 result;
01611 bits8 *r;
01612
01613
01614 if (VARBITLEN(arg) > sizeof(result) * BITS_PER_BYTE)
01615 ereport(ERROR,
01616 (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
01617 errmsg("bigint out of range")));
01618
01619 result = 0;
01620 for (r = VARBITS(arg); r < VARBITEND(arg); r++)
01621 {
01622 result <<= BITS_PER_BYTE;
01623 result |= *r;
01624 }
01625
01626 result >>= VARBITPAD(arg);
01627
01628 PG_RETURN_INT64(result);
01629 }
01630
01631
01632
01633
01634
01635
01636
01637
01638 Datum
01639 bitposition(PG_FUNCTION_ARGS)
01640 {
01641 VarBit *str = PG_GETARG_VARBIT_P(0);
01642 VarBit *substr = PG_GETARG_VARBIT_P(1);
01643 int substr_length,
01644 str_length,
01645 i,
01646 is;
01647 bits8 *s,
01648 *p;
01649 bits8 cmp,
01650 mask1,
01651 mask2,
01652 end_mask,
01653 str_mask;
01654 bool is_match;
01655
01656
01657 substr_length = VARBITLEN(substr);
01658 str_length = VARBITLEN(str);
01659
01660
01661 if ((str_length == 0) || (substr_length > str_length))
01662 PG_RETURN_INT32(0);
01663
01664
01665 if (substr_length == 0)
01666 PG_RETURN_INT32(1);
01667
01668
01669 end_mask = BITMASK << VARBITPAD(substr);
01670 str_mask = BITMASK << VARBITPAD(str);
01671 for (i = 0; i < VARBITBYTES(str) - VARBITBYTES(substr) + 1; i++)
01672 {
01673 for (is = 0; is < BITS_PER_BYTE; is++)
01674 {
01675 is_match = true;
01676 p = VARBITS(str) + i;
01677 mask1 = BITMASK >> is;
01678 mask2 = ~mask1;
01679 for (s = VARBITS(substr);
01680 is_match && s < VARBITEND(substr); s++)
01681 {
01682 cmp = *s >> is;
01683 if (s == VARBITEND(substr) - 1)
01684 {
01685 mask1 &= end_mask >> is;
01686 if (p == VARBITEND(str) - 1)
01687 {
01688
01689 if (mask1 & ~str_mask)
01690 {
01691 is_match = false;
01692 break;
01693 }
01694 mask1 &= str_mask;
01695 }
01696 }
01697 is_match = ((cmp ^ *p) & mask1) == 0;
01698 if (!is_match)
01699 break;
01700
01701 p++;
01702 if (p == VARBITEND(str))
01703 {
01704 mask2 = end_mask << (BITS_PER_BYTE - is);
01705 is_match = mask2 == 0;
01706 #if 0
01707 elog(DEBUG4, "S. %d %d em=%2x sm=%2x r=%d",
01708 i, is, end_mask, mask2, is_match);
01709 #endif
01710 break;
01711 }
01712 cmp = *s << (BITS_PER_BYTE - is);
01713 if (s == VARBITEND(substr) - 1)
01714 {
01715 mask2 &= end_mask << (BITS_PER_BYTE - is);
01716 if (p == VARBITEND(str) - 1)
01717 {
01718 if (mask2 & ~str_mask)
01719 {
01720 is_match = false;
01721 break;
01722 }
01723 mask2 &= str_mask;
01724 }
01725 }
01726 is_match = ((cmp ^ *p) & mask2) == 0;
01727 }
01728
01729 if (is_match)
01730 PG_RETURN_INT32(i * BITS_PER_BYTE + is + 1);
01731 }
01732 }
01733 PG_RETURN_INT32(0);
01734 }
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747 Datum
01748 bitsetbit(PG_FUNCTION_ARGS)
01749 {
01750 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
01751 int32 n = PG_GETARG_INT32(1);
01752 int32 newBit = PG_GETARG_INT32(2);
01753 VarBit *result;
01754 int len,
01755 bitlen;
01756 bits8 *r,
01757 *p;
01758 int byteNo,
01759 bitNo;
01760
01761 bitlen = VARBITLEN(arg1);
01762 if (n < 0 || n >= bitlen)
01763 ereport(ERROR,
01764 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
01765 errmsg("bit index %d out of valid range (0..%d)",
01766 n, bitlen - 1)));
01767
01768
01769
01770
01771 if (newBit != 0 && newBit != 1)
01772 ereport(ERROR,
01773 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
01774 errmsg("new bit must be 0 or 1")));
01775
01776 len = VARSIZE(arg1);
01777 result = (VarBit *) palloc(len);
01778 SET_VARSIZE(result, len);
01779 VARBITLEN(result) = bitlen;
01780
01781 p = VARBITS(arg1);
01782 r = VARBITS(result);
01783
01784 memcpy(r, p, VARBITBYTES(arg1));
01785
01786 byteNo = n / BITS_PER_BYTE;
01787 bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
01788
01789
01790
01791
01792 if (newBit == 0)
01793 r[byteNo] &= (~(1 << bitNo));
01794 else
01795 r[byteNo] |= (1 << bitNo);
01796
01797 PG_RETURN_VARBIT_P(result);
01798 }
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809 Datum
01810 bitgetbit(PG_FUNCTION_ARGS)
01811 {
01812 VarBit *arg1 = PG_GETARG_VARBIT_P(0);
01813 int32 n = PG_GETARG_INT32(1);
01814 int bitlen;
01815 bits8 *p;
01816 int byteNo,
01817 bitNo;
01818
01819 bitlen = VARBITLEN(arg1);
01820 if (n < 0 || n >= bitlen)
01821 ereport(ERROR,
01822 (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
01823 errmsg("bit index %d out of valid range (0..%d)",
01824 n, bitlen - 1)));
01825
01826 p = VARBITS(arg1);
01827
01828 byteNo = n / BITS_PER_BYTE;
01829 bitNo = BITS_PER_BYTE - 1 - (n % BITS_PER_BYTE);
01830
01831 if (p[byteNo] & (1 << bitNo))
01832 PG_RETURN_INT32(1);
01833 else
01834 PG_RETURN_INT32(0);
01835 }