00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "postgres.h"
00016
00017
00018 #include "access/hash.h"
00019 #include "access/tuptoaster.h"
00020 #include "libpq/pqformat.h"
00021 #include "nodes/nodeFuncs.h"
00022 #include "utils/array.h"
00023 #include "utils/builtins.h"
00024 #include "mb/pg_wchar.h"
00025
00026
00027
00028 static int32
00029 anychar_typmodin(ArrayType *ta, const char *typename)
00030 {
00031 int32 typmod;
00032 int32 *tl;
00033 int n;
00034
00035 tl = ArrayGetIntegerTypmods(ta, &n);
00036
00037
00038
00039
00040
00041 if (n != 1)
00042 ereport(ERROR,
00043 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00044 errmsg("invalid type modifier")));
00045
00046 if (*tl < 1)
00047 ereport(ERROR,
00048 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00049 errmsg("length for type %s must be at least 1", typename)));
00050 if (*tl > MaxAttrSize)
00051 ereport(ERROR,
00052 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00053 errmsg("length for type %s cannot exceed %d",
00054 typename, MaxAttrSize)));
00055
00056
00057
00058
00059
00060
00061 typmod = VARHDRSZ + *tl;
00062
00063 return typmod;
00064 }
00065
00066
00067 static char *
00068 anychar_typmodout(int32 typmod)
00069 {
00070 char *res = (char *) palloc(64);
00071
00072 if (typmod > VARHDRSZ)
00073 snprintf(res, 64, "(%d)", (int) (typmod - VARHDRSZ));
00074 else
00075 *res = '\0';
00076
00077 return res;
00078 }
00079
00080
00081
00082
00083
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
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 static BpChar *
00122 bpchar_input(const char *s, size_t len, int32 atttypmod)
00123 {
00124 BpChar *result;
00125 char *r;
00126 size_t maxlen;
00127
00128
00129 if (atttypmod < (int32) VARHDRSZ)
00130 maxlen = len;
00131 else
00132 {
00133 size_t charlen;
00134
00135 maxlen = atttypmod - VARHDRSZ;
00136 charlen = pg_mbstrlen_with_len(s, len);
00137 if (charlen > maxlen)
00138 {
00139
00140 size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
00141 size_t j;
00142
00143
00144
00145
00146
00147
00148 for (j = mbmaxlen; j < len; j++)
00149 {
00150 if (s[j] != ' ')
00151 ereport(ERROR,
00152 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
00153 errmsg("value too long for type character(%d)",
00154 (int) maxlen)));
00155 }
00156
00157
00158
00159
00160
00161 maxlen = len = mbmaxlen;
00162 }
00163 else
00164 {
00165
00166
00167
00168
00169 maxlen = len + (maxlen - charlen);
00170 }
00171 }
00172
00173 result = (BpChar *) palloc(maxlen + VARHDRSZ);
00174 SET_VARSIZE(result, maxlen + VARHDRSZ);
00175 r = VARDATA(result);
00176 memcpy(r, s, len);
00177
00178
00179 if (maxlen > len)
00180 memset(r + len, ' ', maxlen - len);
00181
00182 return result;
00183 }
00184
00185
00186
00187
00188
00189 Datum
00190 bpcharin(PG_FUNCTION_ARGS)
00191 {
00192 char *s = PG_GETARG_CSTRING(0);
00193
00194 #ifdef NOT_USED
00195 Oid typelem = PG_GETARG_OID(1);
00196 #endif
00197 int32 atttypmod = PG_GETARG_INT32(2);
00198 BpChar *result;
00199
00200 result = bpchar_input(s, strlen(s), atttypmod);
00201 PG_RETURN_BPCHAR_P(result);
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211 Datum
00212 bpcharout(PG_FUNCTION_ARGS)
00213 {
00214 Datum txt = PG_GETARG_DATUM(0);
00215
00216 PG_RETURN_CSTRING(TextDatumGetCString(txt));
00217 }
00218
00219
00220
00221
00222 Datum
00223 bpcharrecv(PG_FUNCTION_ARGS)
00224 {
00225 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00226
00227 #ifdef NOT_USED
00228 Oid typelem = PG_GETARG_OID(1);
00229 #endif
00230 int32 atttypmod = PG_GETARG_INT32(2);
00231 BpChar *result;
00232 char *str;
00233 int nbytes;
00234
00235 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
00236 result = bpchar_input(str, nbytes, atttypmod);
00237 pfree(str);
00238 PG_RETURN_BPCHAR_P(result);
00239 }
00240
00241
00242
00243
00244 Datum
00245 bpcharsend(PG_FUNCTION_ARGS)
00246 {
00247
00248 return textsend(fcinfo);
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 Datum
00265 bpchar(PG_FUNCTION_ARGS)
00266 {
00267 BpChar *source = PG_GETARG_BPCHAR_PP(0);
00268 int32 maxlen = PG_GETARG_INT32(1);
00269 bool isExplicit = PG_GETARG_BOOL(2);
00270 BpChar *result;
00271 int32 len;
00272 char *r;
00273 char *s;
00274 int i;
00275 int charlen;
00276
00277
00278
00279 if (maxlen < (int32) VARHDRSZ)
00280 PG_RETURN_BPCHAR_P(source);
00281
00282 maxlen -= VARHDRSZ;
00283
00284 len = VARSIZE_ANY_EXHDR(source);
00285 s = VARDATA_ANY(source);
00286
00287 charlen = pg_mbstrlen_with_len(s, len);
00288
00289
00290 if (charlen == maxlen)
00291 PG_RETURN_BPCHAR_P(source);
00292
00293 if (charlen > maxlen)
00294 {
00295
00296 size_t maxmblen;
00297
00298 maxmblen = pg_mbcharcliplen(s, len, maxlen);
00299
00300 if (!isExplicit)
00301 {
00302 for (i = maxmblen; i < len; i++)
00303 if (s[i] != ' ')
00304 ereport(ERROR,
00305 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
00306 errmsg("value too long for type character(%d)",
00307 maxlen)));
00308 }
00309
00310 len = maxmblen;
00311
00312
00313
00314
00315
00316 maxlen = len;
00317 }
00318 else
00319 {
00320
00321
00322
00323
00324 maxlen = len + (maxlen - charlen);
00325 }
00326
00327 Assert(maxlen >= len);
00328
00329 result = palloc(maxlen + VARHDRSZ);
00330 SET_VARSIZE(result, maxlen + VARHDRSZ);
00331 r = VARDATA(result);
00332
00333 memcpy(r, s, len);
00334
00335
00336 if (maxlen > len)
00337 memset(r + len, ' ', maxlen - len);
00338
00339 PG_RETURN_BPCHAR_P(result);
00340 }
00341
00342
00343
00344
00345
00346 Datum
00347 char_bpchar(PG_FUNCTION_ARGS)
00348 {
00349 char c = PG_GETARG_CHAR(0);
00350 BpChar *result;
00351
00352 result = (BpChar *) palloc(VARHDRSZ + 1);
00353
00354 SET_VARSIZE(result, VARHDRSZ + 1);
00355 *(VARDATA(result)) = c;
00356
00357 PG_RETURN_BPCHAR_P(result);
00358 }
00359
00360
00361
00362
00363
00364 Datum
00365 bpchar_name(PG_FUNCTION_ARGS)
00366 {
00367 BpChar *s = PG_GETARG_BPCHAR_PP(0);
00368 char *s_data;
00369 Name result;
00370 int len;
00371
00372 len = VARSIZE_ANY_EXHDR(s);
00373 s_data = VARDATA_ANY(s);
00374
00375
00376 if (len >= NAMEDATALEN)
00377 len = pg_mbcliplen(s_data, len, NAMEDATALEN - 1);
00378
00379
00380 while (len > 0)
00381 {
00382 if (s_data[len - 1] != ' ')
00383 break;
00384 len--;
00385 }
00386
00387
00388 result = (Name) palloc0(NAMEDATALEN);
00389 memcpy(NameStr(*result), s_data, len);
00390
00391 PG_RETURN_NAME(result);
00392 }
00393
00394
00395
00396
00397
00398
00399
00400 Datum
00401 name_bpchar(PG_FUNCTION_ARGS)
00402 {
00403 Name s = PG_GETARG_NAME(0);
00404 BpChar *result;
00405
00406 result = (BpChar *) cstring_to_text(NameStr(*s));
00407 PG_RETURN_BPCHAR_P(result);
00408 }
00409
00410 Datum
00411 bpchartypmodin(PG_FUNCTION_ARGS)
00412 {
00413 ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
00414
00415 PG_RETURN_INT32(anychar_typmodin(ta, "char"));
00416 }
00417
00418 Datum
00419 bpchartypmodout(PG_FUNCTION_ARGS)
00420 {
00421 int32 typmod = PG_GETARG_INT32(0);
00422
00423 PG_RETURN_CSTRING(anychar_typmodout(typmod));
00424 }
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 static VarChar *
00450 varchar_input(const char *s, size_t len, int32 atttypmod)
00451 {
00452 VarChar *result;
00453 size_t maxlen;
00454
00455 maxlen = atttypmod - VARHDRSZ;
00456
00457 if (atttypmod >= (int32) VARHDRSZ && len > maxlen)
00458 {
00459
00460 size_t mbmaxlen = pg_mbcharcliplen(s, len, maxlen);
00461 size_t j;
00462
00463 for (j = mbmaxlen; j < len; j++)
00464 {
00465 if (s[j] != ' ')
00466 ereport(ERROR,
00467 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
00468 errmsg("value too long for type character varying(%d)",
00469 (int) maxlen)));
00470 }
00471
00472 len = mbmaxlen;
00473 }
00474
00475 result = (VarChar *) cstring_to_text_with_len(s, len);
00476 return result;
00477 }
00478
00479
00480
00481
00482
00483 Datum
00484 varcharin(PG_FUNCTION_ARGS)
00485 {
00486 char *s = PG_GETARG_CSTRING(0);
00487
00488 #ifdef NOT_USED
00489 Oid typelem = PG_GETARG_OID(1);
00490 #endif
00491 int32 atttypmod = PG_GETARG_INT32(2);
00492 VarChar *result;
00493
00494 result = varchar_input(s, strlen(s), atttypmod);
00495 PG_RETURN_VARCHAR_P(result);
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505 Datum
00506 varcharout(PG_FUNCTION_ARGS)
00507 {
00508 Datum txt = PG_GETARG_DATUM(0);
00509
00510 PG_RETURN_CSTRING(TextDatumGetCString(txt));
00511 }
00512
00513
00514
00515
00516 Datum
00517 varcharrecv(PG_FUNCTION_ARGS)
00518 {
00519 StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
00520
00521 #ifdef NOT_USED
00522 Oid typelem = PG_GETARG_OID(1);
00523 #endif
00524 int32 atttypmod = PG_GETARG_INT32(2);
00525 VarChar *result;
00526 char *str;
00527 int nbytes;
00528
00529 str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
00530 result = varchar_input(str, nbytes, atttypmod);
00531 pfree(str);
00532 PG_RETURN_VARCHAR_P(result);
00533 }
00534
00535
00536
00537
00538 Datum
00539 varcharsend(PG_FUNCTION_ARGS)
00540 {
00541
00542 return textsend(fcinfo);
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552 Datum
00553 varchar_transform(PG_FUNCTION_ARGS)
00554 {
00555 FuncExpr *expr = (FuncExpr *) PG_GETARG_POINTER(0);
00556 Node *ret = NULL;
00557 Node *typmod;
00558
00559 Assert(IsA(expr, FuncExpr));
00560 Assert(list_length(expr->args) >= 2);
00561
00562 typmod = (Node *) lsecond(expr->args);
00563
00564 if (IsA(typmod, Const) &&!((Const *) typmod)->constisnull)
00565 {
00566 Node *source = (Node *) linitial(expr->args);
00567 int32 old_typmod = exprTypmod(source);
00568 int32 new_typmod = DatumGetInt32(((Const *) typmod)->constvalue);
00569 int32 old_max = old_typmod - VARHDRSZ;
00570 int32 new_max = new_typmod - VARHDRSZ;
00571
00572 if (new_typmod < 0 || (old_typmod >= 0 && old_max <= new_max))
00573 ret = relabel_to_typmod(source, new_typmod);
00574 }
00575
00576 PG_RETURN_POINTER(ret);
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591 Datum
00592 varchar(PG_FUNCTION_ARGS)
00593 {
00594 VarChar *source = PG_GETARG_VARCHAR_PP(0);
00595 int32 typmod = PG_GETARG_INT32(1);
00596 bool isExplicit = PG_GETARG_BOOL(2);
00597 int32 len,
00598 maxlen;
00599 size_t maxmblen;
00600 int i;
00601 char *s_data;
00602
00603 len = VARSIZE_ANY_EXHDR(source);
00604 s_data = VARDATA_ANY(source);
00605 maxlen = typmod - VARHDRSZ;
00606
00607
00608 if (maxlen < 0 || len <= maxlen)
00609 PG_RETURN_VARCHAR_P(source);
00610
00611
00612
00613
00614 maxmblen = pg_mbcharcliplen(s_data, len, maxlen);
00615
00616 if (!isExplicit)
00617 {
00618 for (i = maxmblen; i < len; i++)
00619 if (s_data[i] != ' ')
00620 ereport(ERROR,
00621 (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
00622 errmsg("value too long for type character varying(%d)",
00623 maxlen)));
00624 }
00625
00626 PG_RETURN_VARCHAR_P((VarChar *) cstring_to_text_with_len(s_data,
00627 maxmblen));
00628 }
00629
00630 Datum
00631 varchartypmodin(PG_FUNCTION_ARGS)
00632 {
00633 ArrayType *ta = PG_GETARG_ARRAYTYPE_P(0);
00634
00635 PG_RETURN_INT32(anychar_typmodin(ta, "varchar"));
00636 }
00637
00638 Datum
00639 varchartypmodout(PG_FUNCTION_ARGS)
00640 {
00641 int32 typmod = PG_GETARG_INT32(0);
00642
00643 PG_RETURN_CSTRING(anychar_typmodout(typmod));
00644 }
00645
00646
00647
00648
00649
00650
00651
00652 static int
00653 bcTruelen(BpChar *arg)
00654 {
00655 char *s = VARDATA_ANY(arg);
00656 int i;
00657 int len;
00658
00659 len = VARSIZE_ANY_EXHDR(arg);
00660 for (i = len - 1; i >= 0; i--)
00661 {
00662 if (s[i] != ' ')
00663 break;
00664 }
00665 return i + 1;
00666 }
00667
00668 Datum
00669 bpcharlen(PG_FUNCTION_ARGS)
00670 {
00671 BpChar *arg = PG_GETARG_BPCHAR_PP(0);
00672 int len;
00673
00674
00675 len = bcTruelen(arg);
00676
00677
00678 if (pg_database_encoding_max_length() != 1)
00679 len = pg_mbstrlen_with_len(VARDATA_ANY(arg), len);
00680
00681 PG_RETURN_INT32(len);
00682 }
00683
00684 Datum
00685 bpcharoctetlen(PG_FUNCTION_ARGS)
00686 {
00687 Datum arg = PG_GETARG_DATUM(0);
00688
00689
00690 PG_RETURN_INT32(toast_raw_datum_size(arg) - VARHDRSZ);
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702 Datum
00703 bpchareq(PG_FUNCTION_ARGS)
00704 {
00705 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00706 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00707 int len1,
00708 len2;
00709 bool result;
00710
00711 len1 = bcTruelen(arg1);
00712 len2 = bcTruelen(arg2);
00713
00714
00715
00716
00717
00718 if (len1 != len2)
00719 result = false;
00720 else
00721 result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) == 0);
00722
00723 PG_FREE_IF_COPY(arg1, 0);
00724 PG_FREE_IF_COPY(arg2, 1);
00725
00726 PG_RETURN_BOOL(result);
00727 }
00728
00729 Datum
00730 bpcharne(PG_FUNCTION_ARGS)
00731 {
00732 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00733 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00734 int len1,
00735 len2;
00736 bool result;
00737
00738 len1 = bcTruelen(arg1);
00739 len2 = bcTruelen(arg2);
00740
00741
00742
00743
00744
00745 if (len1 != len2)
00746 result = true;
00747 else
00748 result = (memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), len1) != 0);
00749
00750 PG_FREE_IF_COPY(arg1, 0);
00751 PG_FREE_IF_COPY(arg2, 1);
00752
00753 PG_RETURN_BOOL(result);
00754 }
00755
00756 Datum
00757 bpcharlt(PG_FUNCTION_ARGS)
00758 {
00759 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00760 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00761 int len1,
00762 len2;
00763 int cmp;
00764
00765 len1 = bcTruelen(arg1);
00766 len2 = bcTruelen(arg2);
00767
00768 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
00769 PG_GET_COLLATION());
00770
00771 PG_FREE_IF_COPY(arg1, 0);
00772 PG_FREE_IF_COPY(arg2, 1);
00773
00774 PG_RETURN_BOOL(cmp < 0);
00775 }
00776
00777 Datum
00778 bpcharle(PG_FUNCTION_ARGS)
00779 {
00780 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00781 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00782 int len1,
00783 len2;
00784 int cmp;
00785
00786 len1 = bcTruelen(arg1);
00787 len2 = bcTruelen(arg2);
00788
00789 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
00790 PG_GET_COLLATION());
00791
00792 PG_FREE_IF_COPY(arg1, 0);
00793 PG_FREE_IF_COPY(arg2, 1);
00794
00795 PG_RETURN_BOOL(cmp <= 0);
00796 }
00797
00798 Datum
00799 bpchargt(PG_FUNCTION_ARGS)
00800 {
00801 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00802 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00803 int len1,
00804 len2;
00805 int cmp;
00806
00807 len1 = bcTruelen(arg1);
00808 len2 = bcTruelen(arg2);
00809
00810 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
00811 PG_GET_COLLATION());
00812
00813 PG_FREE_IF_COPY(arg1, 0);
00814 PG_FREE_IF_COPY(arg2, 1);
00815
00816 PG_RETURN_BOOL(cmp > 0);
00817 }
00818
00819 Datum
00820 bpcharge(PG_FUNCTION_ARGS)
00821 {
00822 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00823 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00824 int len1,
00825 len2;
00826 int cmp;
00827
00828 len1 = bcTruelen(arg1);
00829 len2 = bcTruelen(arg2);
00830
00831 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
00832 PG_GET_COLLATION());
00833
00834 PG_FREE_IF_COPY(arg1, 0);
00835 PG_FREE_IF_COPY(arg2, 1);
00836
00837 PG_RETURN_BOOL(cmp >= 0);
00838 }
00839
00840 Datum
00841 bpcharcmp(PG_FUNCTION_ARGS)
00842 {
00843 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00844 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00845 int len1,
00846 len2;
00847 int cmp;
00848
00849 len1 = bcTruelen(arg1);
00850 len2 = bcTruelen(arg2);
00851
00852 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
00853 PG_GET_COLLATION());
00854
00855 PG_FREE_IF_COPY(arg1, 0);
00856 PG_FREE_IF_COPY(arg2, 1);
00857
00858 PG_RETURN_INT32(cmp);
00859 }
00860
00861 Datum
00862 bpchar_larger(PG_FUNCTION_ARGS)
00863 {
00864 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00865 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00866 int len1,
00867 len2;
00868 int cmp;
00869
00870 len1 = bcTruelen(arg1);
00871 len2 = bcTruelen(arg2);
00872
00873 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
00874 PG_GET_COLLATION());
00875
00876 PG_RETURN_BPCHAR_P((cmp >= 0) ? arg1 : arg2);
00877 }
00878
00879 Datum
00880 bpchar_smaller(PG_FUNCTION_ARGS)
00881 {
00882 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00883 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00884 int len1,
00885 len2;
00886 int cmp;
00887
00888 len1 = bcTruelen(arg1);
00889 len2 = bcTruelen(arg2);
00890
00891 cmp = varstr_cmp(VARDATA_ANY(arg1), len1, VARDATA_ANY(arg2), len2,
00892 PG_GET_COLLATION());
00893
00894 PG_RETURN_BPCHAR_P((cmp <= 0) ? arg1 : arg2);
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906 Datum
00907 hashbpchar(PG_FUNCTION_ARGS)
00908 {
00909 BpChar *key = PG_GETARG_BPCHAR_PP(0);
00910 char *keydata;
00911 int keylen;
00912 Datum result;
00913
00914 keydata = VARDATA_ANY(key);
00915 keylen = bcTruelen(key);
00916
00917 result = hash_any((unsigned char *) keydata, keylen);
00918
00919
00920 PG_FREE_IF_COPY(key, 0);
00921
00922 return result;
00923 }
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933 static int
00934 internal_bpchar_pattern_compare(BpChar *arg1, BpChar *arg2)
00935 {
00936 int result;
00937 int len1,
00938 len2;
00939
00940 len1 = bcTruelen(arg1);
00941 len2 = bcTruelen(arg2);
00942
00943 result = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
00944 if (result != 0)
00945 return result;
00946 else if (len1 < len2)
00947 return -1;
00948 else if (len1 > len2)
00949 return 1;
00950 else
00951 return 0;
00952 }
00953
00954
00955 Datum
00956 bpchar_pattern_lt(PG_FUNCTION_ARGS)
00957 {
00958 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00959 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00960 int result;
00961
00962 result = internal_bpchar_pattern_compare(arg1, arg2);
00963
00964 PG_FREE_IF_COPY(arg1, 0);
00965 PG_FREE_IF_COPY(arg2, 1);
00966
00967 PG_RETURN_BOOL(result < 0);
00968 }
00969
00970
00971 Datum
00972 bpchar_pattern_le(PG_FUNCTION_ARGS)
00973 {
00974 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00975 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00976 int result;
00977
00978 result = internal_bpchar_pattern_compare(arg1, arg2);
00979
00980 PG_FREE_IF_COPY(arg1, 0);
00981 PG_FREE_IF_COPY(arg2, 1);
00982
00983 PG_RETURN_BOOL(result <= 0);
00984 }
00985
00986
00987 Datum
00988 bpchar_pattern_ge(PG_FUNCTION_ARGS)
00989 {
00990 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
00991 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
00992 int result;
00993
00994 result = internal_bpchar_pattern_compare(arg1, arg2);
00995
00996 PG_FREE_IF_COPY(arg1, 0);
00997 PG_FREE_IF_COPY(arg2, 1);
00998
00999 PG_RETURN_BOOL(result >= 0);
01000 }
01001
01002
01003 Datum
01004 bpchar_pattern_gt(PG_FUNCTION_ARGS)
01005 {
01006 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
01007 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
01008 int result;
01009
01010 result = internal_bpchar_pattern_compare(arg1, arg2);
01011
01012 PG_FREE_IF_COPY(arg1, 0);
01013 PG_FREE_IF_COPY(arg2, 1);
01014
01015 PG_RETURN_BOOL(result > 0);
01016 }
01017
01018
01019 Datum
01020 btbpchar_pattern_cmp(PG_FUNCTION_ARGS)
01021 {
01022 BpChar *arg1 = PG_GETARG_BPCHAR_PP(0);
01023 BpChar *arg2 = PG_GETARG_BPCHAR_PP(1);
01024 int result;
01025
01026 result = internal_bpchar_pattern_compare(arg1, arg2);
01027
01028 PG_FREE_IF_COPY(arg1, 0);
01029 PG_FREE_IF_COPY(arg2, 1);
01030
01031 PG_RETURN_INT32(result);
01032 }