00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "postgres.h"
00015 #include "executor/spi.h"
00016 #include "funcapi.h"
00017 #include "utils/hsearch.h"
00018 #include "utils/memutils.h"
00019
00020 #include "veil_version.h"
00021 #include "veil_funcs.h"
00022 #include "veil_datatypes.h"
00023
00024
00025 # if PG_VERSION_GE(8, 2)
00026 PG_MODULE_MAGIC;
00027 # endif
00028
00029 # if PG_VERSION_GE(8, 3)
00030 #define VEIL_SET_VARSIZE(new_t,t) \
00031 SET_VARSIZE(new_t, t);
00032 #else
00033 #define VEIL_SET_VARSIZE(new_t,t) \
00034 VARATT_SIZEP(new_t) = t;
00035 # endif
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 static char *
00051 strfromtext(text *in)
00052 {
00053 char *out = palloc(VARSIZE(in) - VARHDRSZ + 1);
00054 memcpy(out, VARDATA(in), VARSIZE(in) - VARHDRSZ);
00055 out[VARSIZE(in) - VARHDRSZ] = '\0';
00056
00057 return out;
00058 }
00059
00060
00061
00062
00063
00064
00065
00066 static text *
00067 textfromstr(char *in)
00068 {
00069 int len = strlen(in);
00070 text *out = palloc(len + VARHDRSZ);
00071 memcpy(VARDATA(out), in, len);
00072 VEIL_SET_VARSIZE(out, (len + VARHDRSZ));
00073
00074 return out;
00075 }
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static text *
00086 textfromstrn(char *in, int limit)
00087 {
00088 int len = strlen(in);
00089 text *out;
00090
00091 if (limit < len) {
00092 len = limit;
00093 }
00094
00095 out = palloc(len + VARHDRSZ);
00096 memcpy(VARDATA(out), in, len);
00097 VEIL_SET_VARSIZE(out, (len + VARHDRSZ));
00098
00099 return out;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 static char *
00110 copystr(char *str)
00111 {
00112 char *new = palloc((sizeof(char) * strlen(str) + 1));
00113 strcpy(new, str);
00114 return new;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 static char *
00124 strfromint(int4 val)
00125 {
00126 char *new = palloc((sizeof(char) * 17));
00127
00128 sprintf(new, "%d", val);
00129 return new;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138 static char *
00139 strfrombool(bool val)
00140 {
00141 char *new = palloc((sizeof(char) * 2));
00142 if (val) {
00143 strcpy(new, "t");
00144 }
00145 else {
00146 strcpy(new, "f");
00147 }
00148 return new;
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 static void
00160 ensure_init()
00161 {
00162 bool success = false;
00163 TransactionId this_xid;
00164 int ok;
00165 HTAB *hash;
00166 static bool done = false;
00167 static TransactionId xid = 0;
00168
00169 if (!done) {
00170 this_xid = GetCurrentTransactionId();
00171 if (xid == this_xid) {
00172
00173 return;
00174 }
00175 xid = this_xid;
00176 ok = vl_spi_connect();
00177 if (ok != SPI_OK_CONNECT) {
00178 ereport(ERROR,
00179 (errcode(ERRCODE_INTERNAL_ERROR),
00180 errmsg("failed to initialise session (1)"),
00181 errdetail("SPI_connect() failed, returning %d.", ok)));
00182 }
00183
00184 hash = vl_get_shared_hash();
00185 (void) vl_bool_from_query("select veil_init(FALSE)", &success);
00186
00187 if (!success) {
00188 ereport(ERROR,
00189 (errcode(ERRCODE_INTERNAL_ERROR),
00190 errmsg("failed to initialise session (2)"),
00191 errdetail("veil_init() did not return true.")));
00192 }
00193
00194 ok = vl_spi_finish();
00195 if (ok != SPI_OK_FINISH) {
00196 ereport(ERROR,
00197 (errcode(ERRCODE_INTERNAL_ERROR),
00198 errmsg("failed to initialise session (3)"),
00199 errdetail("SPI_finish() failed, returning %d.", ok)));
00200 }
00201 done = true;
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 extern void
00214 vl_type_mismatch(char *name,
00215 ObjType expected,
00216 ObjType got)
00217 {
00218 ereport(ERROR,
00219 (errcode(ERRCODE_INTERNAL_ERROR),
00220 errmsg("type mismatch in %s: expected %s, got %s",
00221 name, vl_ObjTypeName(expected), vl_ObjTypeName(got)),
00222 errdetail("Variable %s is not of the expected type.", name)));
00223 }
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 static Int4Var *
00236 GetInt4Var(char *name,
00237 bool create)
00238 {
00239 VarEntry *var;
00240 Int4Var *i4v;
00241
00242 var = vl_lookup_variable(name);
00243 i4v = (Int4Var *) var->obj;
00244
00245 if (i4v) {
00246 if (i4v->type != OBJ_INT4) {
00247 vl_type_mismatch(name, OBJ_INT4, i4v->type);
00248 }
00249 }
00250 else {
00251 if (create) {
00252 var->obj = (Object *) vl_NewInt4(var->shared);
00253 i4v = (Int4Var *) var->obj;
00254 }
00255 else {
00256 vl_type_mismatch(name, OBJ_INT4, OBJ_UNDEFINED);
00257 }
00258 }
00259 return i4v;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 static Range *
00273 GetRange(char *name,
00274 bool create)
00275 {
00276 VarEntry *var;
00277 Range *range;
00278
00279 var = vl_lookup_variable(name);
00280 range = (Range *) var->obj;
00281
00282 if (range) {
00283 if (range->type != OBJ_RANGE) {
00284 vl_type_mismatch(name, OBJ_RANGE, range->type);
00285 }
00286 }
00287 else {
00288 if (create) {
00289 var->obj = (Object *) vl_NewRange(var->shared);
00290 range = (Range *) var->obj;
00291 }
00292 else {
00293 vl_type_mismatch(name, OBJ_RANGE, OBJ_UNDEFINED);
00294 }
00295 }
00296 return range;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 static Bitmap *
00313 GetBitmapFromVar(VarEntry *var,
00314 bool allow_empty,
00315 bool allow_ref)
00316 {
00317 Bitmap *bitmap = (Bitmap *) var->obj;
00318
00319 if (bitmap) {
00320 if (bitmap->type != OBJ_BITMAP) {
00321 if (allow_ref && (bitmap->type == OBJ_BITMAP_REF)) {
00322 BitmapRef *bmref = (BitmapRef *) bitmap;
00323 if (bmref->xid == GetCurrentTransactionId()) {
00324 bitmap = bmref->bitmap;
00325 }
00326 else {
00327 ereport(ERROR,
00328 (errcode(ERRCODE_INTERNAL_ERROR),
00329 errmsg("BitmapRef %s is not defined",
00330 var->key),
00331 errhint("Perhaps the name is mis-spelled, or its "
00332 "definition is missing from "
00333 "veil_init().")));
00334 }
00335 }
00336 else {
00337 vl_type_mismatch(var->key, OBJ_BITMAP, bitmap->type);
00338 }
00339 }
00340 }
00341 else {
00342 if (!allow_empty) {
00343 vl_type_mismatch(var->key, OBJ_BITMAP, OBJ_UNDEFINED);
00344 }
00345 }
00346 return bitmap;
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 static Bitmap *
00363 GetBitmap(char *name,
00364 bool allow_empty,
00365 bool allow_ref)
00366 {
00367 VarEntry *var;
00368 Bitmap *bitmap;
00369
00370 var = vl_lookup_variable(name);
00371 bitmap = GetBitmapFromVar(var, allow_empty, allow_ref);
00372
00373 return bitmap;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 static BitmapRef *
00386 GetBitmapRefFromVar(VarEntry *var)
00387 {
00388 BitmapRef *bmref = (BitmapRef *) var->obj;
00389
00390 if (bmref) {
00391 if (bmref->type != OBJ_BITMAP_REF) {
00392 vl_type_mismatch(var->key, OBJ_BITMAP_REF, bmref->type);
00393 }
00394 }
00395 else {
00396 if (var->shared) {
00397 ereport(ERROR,
00398 (errcode(ERRCODE_INTERNAL_ERROR),
00399 errmsg("illegal attempt to define shared BitmapRef %s",
00400 var->key),
00401 errhint("BitmapRefs may only be defined as session, "
00402 "not shared, variables.")));
00403 }
00404
00405 bmref = vl_malloc(sizeof(BitmapRef));
00406 bmref->type = OBJ_BITMAP_REF;
00407 bmref->bitmap = NULL;
00408 var->obj = (Object *) bmref;
00409 }
00410
00411 return bmref;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 static BitmapRef *
00423 GetBitmapRef(char *name)
00424 {
00425 VarEntry *var;
00426 BitmapRef *bmref;
00427
00428 var = vl_lookup_variable(name);
00429 bmref = GetBitmapRefFromVar(var);
00430
00431 return bmref;
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 static BitmapArray *
00446 GetBitmapArrayFromVar(VarEntry *var,
00447 bool allow_empty)
00448 {
00449 BitmapArray *bmarray;
00450 bmarray = (BitmapArray *) var->obj;
00451
00452 if (bmarray) {
00453 if (bmarray->type != OBJ_BITMAP_ARRAY) {
00454 vl_type_mismatch(var->key, OBJ_BITMAP_ARRAY, bmarray->type);
00455 }
00456 }
00457 else {
00458 if (!allow_empty) {
00459 vl_type_mismatch(var->key, OBJ_BITMAP_ARRAY, OBJ_UNDEFINED);
00460 }
00461 }
00462
00463 return bmarray;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 static BitmapArray *
00478 GetBitmapArray(char *name,
00479 bool allow_empty)
00480 {
00481 VarEntry *var;
00482 BitmapArray *bmarray;
00483
00484 var = vl_lookup_variable(name);
00485 bmarray = GetBitmapArrayFromVar(var, allow_empty);
00486
00487 return bmarray;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 static BitmapHash *
00502 GetBitmapHashFromVar(VarEntry *var,
00503 bool allow_empty)
00504 {
00505 BitmapHash *bmhash;
00506 bmhash = (BitmapHash *) var->obj;
00507
00508 if (bmhash) {
00509 if (bmhash->type != OBJ_BITMAP_HASH) {
00510 vl_type_mismatch(var->key, OBJ_BITMAP_HASH, bmhash->type);
00511 }
00512 }
00513 else {
00514 if (!allow_empty) {
00515 vl_type_mismatch(var->key, OBJ_BITMAP_HASH, OBJ_UNDEFINED);
00516 }
00517 }
00518
00519 return bmhash;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 static BitmapHash *
00534 GetBitmapHash(char *name,
00535 bool allow_empty)
00536 {
00537 VarEntry *var;
00538 BitmapHash *bmhash;
00539
00540 var = vl_lookup_variable(name);
00541 bmhash = GetBitmapHashFromVar(var, allow_empty);
00542
00543 return bmhash;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 static Int4Array *
00558 GetInt4ArrayFromVar(VarEntry *var,
00559 bool allow_empty)
00560 {
00561 Int4Array *array;
00562 array = (Int4Array *) var->obj;
00563
00564 if (array) {
00565 if (array->type != OBJ_INT4_ARRAY) {
00566 vl_type_mismatch(var->key, OBJ_INT4_ARRAY, array->type);
00567 }
00568 }
00569 else {
00570 if (!allow_empty) {
00571 vl_type_mismatch(var->key, OBJ_INT4_ARRAY, OBJ_UNDEFINED);
00572 }
00573 }
00574
00575 return array;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589 static Int4Array *
00590 GetInt4Array(char *name,
00591 bool allow_empty)
00592 {
00593 VarEntry *var;
00594 Int4Array *array;
00595
00596 var = vl_lookup_variable(name);
00597 array = GetInt4ArrayFromVar(var, allow_empty);
00598
00599 return array;
00600 }
00601
00602 PG_FUNCTION_INFO_V1(veil_share);
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 Datum
00623 veil_share(PG_FUNCTION_ARGS)
00624 {
00625 char *name;
00626 VarEntry *var;
00627
00628 ensure_init();
00629 name = strfromtext(PG_GETARG_TEXT_P(0));
00630
00631 var = vl_lookup_shared_variable(name);
00632
00633 PG_RETURN_BOOL((var->obj != NULL));
00634 }
00635
00636 PG_FUNCTION_INFO_V1(veil_variables);
00637
00638
00639
00640
00641
00642
00643
00644
00645 Datum
00646 veil_variables(PG_FUNCTION_ARGS)
00647 {
00648 TupleDesc tupdesc;
00649 TupleTableSlot *slot;
00650 AttInMetadata *attinmeta;
00651 FuncCallContext *funcctx;
00652
00653 veil_variable_t *var;
00654 char **values;
00655 HeapTuple tuple;
00656 Datum datum;
00657
00658 if (SRF_IS_FIRSTCALL())
00659 {
00660
00661 MemoryContext oldcontext;
00662
00663 ensure_init();
00664 funcctx = SRF_FIRSTCALL_INIT();
00665 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
00666
00667 tupdesc = RelationNameGetTupleDesc("veil_variable_t");
00668 slot = TupleDescGetSlot(tupdesc);
00669 funcctx->slot = slot;
00670 attinmeta = TupleDescGetAttInMetadata(tupdesc);
00671 funcctx->attinmeta = attinmeta;
00672
00673 MemoryContextSwitchTo(oldcontext);
00674 funcctx->user_fctx = NULL;
00675 }
00676
00677 funcctx = SRF_PERCALL_SETUP();
00678 var = vl_next_variable(funcctx->user_fctx);
00679 funcctx->user_fctx = var;
00680
00681 if (var) {
00682 values = (char **) palloc(3 * sizeof(char *));
00683 values[0] = copystr(var->name);
00684 values[1] = copystr(var->type);
00685 values[2] = strfrombool(var->shared);
00686
00687 slot = funcctx->slot;
00688 attinmeta = funcctx->attinmeta;
00689
00690 tuple = BuildTupleFromCStrings(attinmeta, values);
00691 datum = TupleGetDatum(slot, tuple);
00692 SRF_RETURN_NEXT(funcctx, datum);
00693
00694 }
00695 else {
00696 SRF_RETURN_DONE(funcctx);
00697 }
00698 }
00699
00700
00701 PG_FUNCTION_INFO_V1(veil_init_range);
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 Datum
00715 veil_init_range(PG_FUNCTION_ARGS)
00716 {
00717 int32 min;
00718 int32 max;
00719 Range *range;
00720 char *name;
00721
00722 ensure_init();
00723 name = strfromtext(PG_GETARG_TEXT_P(0));
00724 min = PG_GETARG_INT32(1);
00725 max = PG_GETARG_INT32(2);
00726
00727 range = GetRange(name, true);
00728
00729 range->min = min;
00730 range->max = max;
00731 PG_RETURN_INT32(max + 1 - min);
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 Datum
00744 datum_from_range(int32 min, int32 max)
00745 {
00746 static init_done = false;
00747 static TupleDesc tupdesc;
00748 static AttInMetadata *attinmeta;
00749 TupleTableSlot *slot;
00750 HeapTuple tuple;
00751 char **values;
00752
00753 if (!init_done) {
00754
00755
00756 MemoryContext oldcontext = MemoryContextSwitchTo(TopMemoryContext);
00757
00758 init_done = true;
00759 tupdesc = RelationNameGetTupleDesc("veil_range_t");
00760 slot = TupleDescGetSlot(tupdesc);
00761 attinmeta = TupleDescGetAttInMetadata(tupdesc);
00762
00763 MemoryContextSwitchTo(oldcontext);
00764 }
00765
00766
00767 values = (char **) palloc(2 * sizeof(char *));
00768 values[0] = strfromint(min);
00769 values[1] = strfromint(max);
00770
00771 tuple = BuildTupleFromCStrings(attinmeta, values);
00772 slot = TupleDescGetSlot(tupdesc);
00773
00774
00775 return TupleGetDatum(slot, tuple);
00776 }
00777
00778
00779 PG_FUNCTION_INFO_V1(veil_range);
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 Datum
00792 veil_range(PG_FUNCTION_ARGS)
00793 {
00794 char *name;
00795 Range *range;
00796 Datum datum;
00797
00798 ensure_init();
00799
00800 name = strfromtext(PG_GETARG_TEXT_P(0));
00801 range = GetRange(name, false);
00802
00803 datum = (datum_from_range(range->min, range->max));
00804
00805 PG_RETURN_DATUM(datum);
00806 }
00807
00808 PG_FUNCTION_INFO_V1(veil_init_bitmap);
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 Datum
00823 veil_init_bitmap(PG_FUNCTION_ARGS)
00824 {
00825 char *bitmap_name;
00826 char *range_name;
00827 Bitmap *bitmap;
00828 VarEntry *bitmap_var;
00829 Range *range;
00830
00831 ensure_init();
00832
00833 bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
00834 bitmap_var = vl_lookup_variable(bitmap_name);
00835 bitmap = GetBitmapFromVar(bitmap_var, true, false);
00836 range_name = strfromtext(PG_GETARG_TEXT_P(1));
00837 range = GetRange(range_name, false);
00838
00839 vl_NewBitmap(&bitmap, bitmap_var->shared, range->min, range->max);
00840
00841 bitmap_var->obj = (Object *) bitmap;
00842
00843 PG_RETURN_BOOL(true);
00844 }
00845
00846 PG_FUNCTION_INFO_V1(veil_clear_bitmap);
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 Datum
00857 veil_clear_bitmap(PG_FUNCTION_ARGS)
00858 {
00859 char *bitmap_name;
00860 VarEntry *bitmap_var;
00861 Bitmap *bitmap;
00862
00863 ensure_init();
00864
00865 bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
00866 bitmap_var = vl_lookup_variable(bitmap_name);
00867 bitmap = GetBitmapFromVar(bitmap_var, false, true);
00868
00869 vl_ClearBitmap(bitmap);
00870
00871 PG_RETURN_BOOL(true);
00872 }
00873
00874 PG_FUNCTION_INFO_V1(veil_bitmap_setbit);
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 Datum
00886 veil_bitmap_setbit(PG_FUNCTION_ARGS)
00887 {
00888 char *name;
00889 Bitmap *bitmap;
00890 int32 bit;
00891
00892 ensure_init();
00893
00894 name = strfromtext(PG_GETARG_TEXT_P(0));
00895 bit = PG_GETARG_INT32(1);
00896 bitmap = GetBitmap(name, false, true);
00897 vl_BitmapSetbit(bitmap, bit);
00898
00899 PG_RETURN_BOOL(true);
00900 }
00901
00902 PG_FUNCTION_INFO_V1(veil_bitmap_clearbit);
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 Datum
00914 veil_bitmap_clearbit(PG_FUNCTION_ARGS)
00915 {
00916 char *name;
00917 Bitmap *bitmap;
00918 int32 bit;
00919
00920 ensure_init();
00921
00922 name = strfromtext(PG_GETARG_TEXT_P(0));
00923 bit = PG_GETARG_INT32(1);
00924 bitmap = GetBitmap(name, false, true);
00925 vl_BitmapClearbit(bitmap, bit);
00926
00927 PG_RETURN_BOOL(true);
00928 }
00929
00930 PG_FUNCTION_INFO_V1(veil_bitmap_testbit);
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 Datum
00943 veil_bitmap_testbit(PG_FUNCTION_ARGS)
00944 {
00945 char *name;
00946 Bitmap *bitmap;
00947 int32 bit;
00948 bool result;
00949
00950 ensure_init();
00951
00952 bit = PG_GETARG_INT32(1);
00953 name = strfromtext(PG_GETARG_TEXT_P(0));
00954 bitmap = GetBitmap(name, false, true);
00955
00956 result = vl_BitmapTestbit(bitmap, bit);
00957 PG_RETURN_BOOL(result);
00958 }
00959
00960
00961 PG_FUNCTION_INFO_V1(veil_bitmap_union);
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974 Datum
00975 veil_bitmap_union(PG_FUNCTION_ARGS)
00976 {
00977 char *bitmap1_name;
00978 char *bitmap2_name;
00979 Bitmap *target;
00980 Bitmap *source;
00981
00982 ensure_init();
00983
00984 bitmap1_name = strfromtext(PG_GETARG_TEXT_P(0));
00985 bitmap2_name = strfromtext(PG_GETARG_TEXT_P(1));
00986 target = GetBitmap(bitmap1_name, false, true);
00987 source = GetBitmap(bitmap2_name, false, true);
00988
00989 vl_BitmapUnion(target, source);
00990
00991 PG_RETURN_BOOL(true);
00992 }
00993
00994
00995 PG_FUNCTION_INFO_V1(veil_bitmap_intersect);
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008 Datum
01009 veil_bitmap_intersect(PG_FUNCTION_ARGS)
01010 {
01011 char *bitmap1_name;
01012 char *bitmap2_name;
01013 Bitmap *target;
01014 Bitmap *source;
01015
01016 ensure_init();
01017
01018 bitmap1_name = strfromtext(PG_GETARG_TEXT_P(0));
01019 bitmap2_name = strfromtext(PG_GETARG_TEXT_P(1));
01020 target = GetBitmap(bitmap1_name, false, true);
01021 source = GetBitmap(bitmap2_name, false, true);
01022
01023 vl_BitmapIntersect(target, source);
01024 PG_RETURN_BOOL(true);
01025 }
01026
01027
01028 PG_FUNCTION_INFO_V1(veil_bitmap_bits);
01029
01030
01031
01032
01033
01034
01035
01036
01037 Datum
01038 veil_bitmap_bits(PG_FUNCTION_ARGS)
01039 {
01040 struct bitmap_bits_state {
01041 Bitmap *bitmap;
01042 int32 bit;
01043 } *state;
01044 FuncCallContext *funcctx;
01045 MemoryContext oldcontext;
01046 char *name;
01047 bool result;
01048 bool found;
01049 Datum datum;
01050
01051 if (SRF_IS_FIRSTCALL())
01052 {
01053
01054 ensure_init();
01055
01056 funcctx = SRF_FIRSTCALL_INIT();
01057 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
01058 state = palloc(sizeof(struct bitmap_bits_state));
01059 MemoryContextSwitchTo(oldcontext);
01060
01061 name = strfromtext(PG_GETARG_TEXT_P(0));
01062 state->bitmap = GetBitmap(name, false, true);
01063
01064 if (!state->bitmap) {
01065 ereport(ERROR,
01066 (errcode(ERRCODE_INTERNAL_ERROR),
01067 errmsg("Bitmap %s is not defined",
01068 name),
01069 errhint("Perhaps the name is mis-spelled, or its ",
01070 "definition is missing from veil_init().")));
01071 }
01072
01073 state->bit = state->bitmap->bitzero;
01074 funcctx->user_fctx = state;
01075 }
01076
01077 funcctx = SRF_PERCALL_SETUP();
01078 state = funcctx->user_fctx;
01079
01080 state->bit = vl_BitmapNextBit(state->bitmap, state->bit, &found);
01081
01082 if (found) {
01083 datum = Int32GetDatum(state->bit);
01084 state->bit++;
01085 SRF_RETURN_NEXT(funcctx, datum);
01086 }
01087 else {
01088 SRF_RETURN_DONE(funcctx);
01089 }
01090 }
01091
01092 PG_FUNCTION_INFO_V1(veil_bitmap_range);
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102 Datum
01103 veil_bitmap_range(PG_FUNCTION_ARGS)
01104 {
01105 char *name;
01106 Bitmap *bitmap;
01107
01108 ensure_init();
01109
01110 name = strfromtext(PG_GETARG_TEXT_P(0));
01111 bitmap = GetBitmap(name, false, true);
01112
01113 if (!bitmap) {
01114 ereport(ERROR,
01115 (errcode(ERRCODE_INTERNAL_ERROR),
01116 errmsg("Bitmap %s is not defined",
01117 name),
01118 errhint("Perhaps the name is mis-spelled, or its ",
01119 "definition is missing from veil_init().")));
01120 }
01121
01122 PG_RETURN_DATUM(datum_from_range(bitmap->bitzero, bitmap->bitmax));
01123 }
01124
01125
01126 PG_FUNCTION_INFO_V1(veil_init_bitmap_array);
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 Datum
01140 veil_init_bitmap_array(PG_FUNCTION_ARGS)
01141 {
01142 char *bmarray_name;
01143 char *arrayrange_name;
01144 char *maprange_name;
01145 VarEntry *bmarray_var;
01146 BitmapArray *bmarray;
01147 Range *arrayrange;
01148 Range *maprange;
01149
01150 ensure_init();
01151
01152 bmarray_name = strfromtext(PG_GETARG_TEXT_P(0));
01153 bmarray_var = vl_lookup_variable(bmarray_name);
01154 bmarray = GetBitmapArrayFromVar(bmarray_var, true);
01155
01156 arrayrange_name = strfromtext(PG_GETARG_TEXT_P(1));
01157 arrayrange = GetRange(arrayrange_name, false);
01158 maprange_name = strfromtext(PG_GETARG_TEXT_P(2));
01159 maprange = GetRange(maprange_name, false);
01160
01161 vl_NewBitmapArray(&bmarray, bmarray_var->shared,
01162 arrayrange->min, arrayrange->max,
01163 maprange->min, maprange->max);
01164
01165 bmarray_var->obj = (Object *) bmarray;
01166
01167 PG_RETURN_BOOL(true);
01168 }
01169
01170 PG_FUNCTION_INFO_V1(veil_clear_bitmap_array);
01171
01172
01173
01174
01175
01176
01177
01178
01179 Datum
01180 veil_clear_bitmap_array(PG_FUNCTION_ARGS)
01181 {
01182 char *bmarray_name;
01183 VarEntry *bmarray_var;
01184 BitmapArray *bmarray;
01185
01186 ensure_init();
01187
01188 bmarray_name = strfromtext(PG_GETARG_TEXT_P(0));
01189 bmarray_var = vl_lookup_variable(bmarray_name);
01190 bmarray = GetBitmapArrayFromVar(bmarray_var, false);
01191
01192 vl_ClearBitmapArray(bmarray);
01193
01194 PG_RETURN_BOOL(true);
01195 }
01196
01197 PG_FUNCTION_INFO_V1(veil_bitmap_from_array);
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 Datum
01212 veil_bitmap_from_array(PG_FUNCTION_ARGS)
01213 {
01214 text *bmref_text;
01215 char *bmref_name;
01216 BitmapRef *bmref;
01217 char *bmarray_name;
01218 VarEntry *bmarray_var;
01219 BitmapArray *bmarray;
01220 int32 arrayelem;
01221 Bitmap *bitmap;
01222
01223 bmref_text = PG_GETARG_TEXT_P(0);
01224 bmref_name = strfromtext(bmref_text);
01225 bmref = GetBitmapRef(bmref_name);
01226
01227 bmarray_name = strfromtext(PG_GETARG_TEXT_P(1));
01228 bmarray = GetBitmapArray(bmarray_name, false);
01229
01230 arrayelem = PG_GETARG_INT32(2);
01231 bitmap = vl_BitmapFromArray(bmarray, arrayelem);
01232
01233 bmref->bitmap = bitmap;
01234 bmref->xid = GetCurrentTransactionId();
01235 PG_RETURN_TEXT_P(bmref_text);
01236 }
01237
01238 PG_FUNCTION_INFO_V1(veil_bitmap_array_testbit);
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250 Datum
01251 veil_bitmap_array_testbit(PG_FUNCTION_ARGS)
01252 {
01253 char *name;
01254 BitmapArray *bmarray;
01255 Bitmap *bitmap;
01256 int32 arrayelem;
01257 int32 bit;
01258
01259 ensure_init();
01260
01261 arrayelem = PG_GETARG_INT32(1);
01262 bit = PG_GETARG_INT32(2);
01263
01264 name = strfromtext(PG_GETARG_TEXT_P(0));
01265 bmarray = GetBitmapArray(name, false);
01266
01267 bitmap = vl_BitmapFromArray(bmarray, arrayelem);
01268 if (bitmap) {
01269 PG_RETURN_BOOL(vl_BitmapTestbit(bitmap, bit));
01270 }
01271 else {
01272 PG_RETURN_BOOL(false);
01273 }
01274 }
01275
01276
01277 PG_FUNCTION_INFO_V1(veil_bitmap_array_setbit);
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289 Datum
01290 veil_bitmap_array_setbit(PG_FUNCTION_ARGS)
01291 {
01292 char *name;
01293 BitmapArray *bmarray;
01294 Bitmap *bitmap;
01295 int32 arrayelem;
01296 int32 bit;
01297
01298 ensure_init();
01299
01300 arrayelem = PG_GETARG_INT32(1);
01301 bit = PG_GETARG_INT32(2);
01302 name = strfromtext(PG_GETARG_TEXT_P(0));
01303 bmarray = GetBitmapArray(name, false);
01304
01305 bitmap = vl_BitmapFromArray(bmarray, arrayelem);
01306 if (bitmap) {
01307 vl_BitmapSetbit(bitmap, bit);
01308 PG_RETURN_BOOL(true);
01309 }
01310 else {
01311 ereport(ERROR,
01312 (errcode(ERRCODE_INTERNAL_ERROR),
01313 errmsg("Bitmap Array range error (%d not in %d..%d)",
01314 arrayelem, bmarray->arrayzero, bmarray->arraymax),
01315 errdetail("Attempt to reference BitmapArray element "
01316 "outside of the BitmapArray's defined range")));
01317 }
01318 }
01319
01320
01321 PG_FUNCTION_INFO_V1(veil_bitmap_array_clearbit);
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333 Datum
01334 veil_bitmap_array_clearbit(PG_FUNCTION_ARGS)
01335 {
01336 char *name;
01337 BitmapArray *bmarray;
01338 Bitmap *bitmap;
01339 int32 arrayelem;
01340 int32 bit;
01341
01342 ensure_init();
01343
01344 arrayelem = PG_GETARG_INT32(1);
01345 bit = PG_GETARG_INT32(2);
01346 name = strfromtext(PG_GETARG_TEXT_P(0));
01347 bmarray = GetBitmapArray(name, false);
01348
01349 bitmap = vl_BitmapFromArray(bmarray, arrayelem);
01350 if (bitmap) {
01351 vl_BitmapClearbit(bitmap, bit);
01352 PG_RETURN_BOOL(true);
01353 }
01354 else {
01355 ereport(ERROR,
01356 (errcode(ERRCODE_INTERNAL_ERROR),
01357 errmsg("Bitmap Array range error (%d not in %d..%d)",
01358 arrayelem, bmarray->arrayzero, bmarray->arraymax),
01359 errdetail("Attempt to reference BitmapArray element "
01360 "outside of the BitmapArray's defined range")));
01361 }
01362 }
01363
01364
01365 PG_FUNCTION_INFO_V1(veil_union_from_bitmap_array);
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379 Datum
01380 veil_union_from_bitmap_array(PG_FUNCTION_ARGS)
01381 {
01382 char *bitmap_name;
01383 char *bmarray_name;
01384 Bitmap *target;
01385 BitmapArray *bmarray;
01386 Bitmap *bitmap;
01387 int32 arrayelem;
01388
01389 ensure_init();
01390
01391 arrayelem = PG_GETARG_INT32(2);
01392
01393 bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
01394 bmarray_name = strfromtext(PG_GETARG_TEXT_P(1));
01395 target = GetBitmap(bitmap_name, false, true);
01396 bmarray = GetBitmapArray(bmarray_name, false);
01397
01398 bitmap = vl_BitmapFromArray(bmarray, arrayelem);
01399 if (bitmap) {
01400 vl_BitmapUnion(target, bitmap);
01401 }
01402 PG_RETURN_BOOL(true);
01403 }
01404
01405
01406 PG_FUNCTION_INFO_V1(veil_intersect_from_bitmap_array);
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420 Datum
01421 veil_intersect_from_bitmap_array(PG_FUNCTION_ARGS)
01422 {
01423 char *bitmap_name;
01424 char *bmarray_name;
01425 Bitmap *target;
01426 BitmapArray *bmarray;
01427 Bitmap *bitmap;
01428 int32 arrayelem;
01429
01430 ensure_init();
01431
01432 arrayelem = PG_GETARG_INT32(2);
01433
01434 bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
01435 bmarray_name = strfromtext(PG_GETARG_TEXT_P(1));
01436 target = GetBitmap(bitmap_name, false, true);
01437 bmarray = GetBitmapArray(bmarray_name, false);
01438
01439 bitmap = vl_BitmapFromArray(bmarray, arrayelem);
01440 if (bitmap) {
01441 vl_BitmapIntersect(target, bitmap);
01442 }
01443 PG_RETURN_BOOL(true);
01444 }
01445
01446
01447 PG_FUNCTION_INFO_V1(veil_bitmap_array_bits);
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458 Datum
01459 veil_bitmap_array_bits(PG_FUNCTION_ARGS)
01460 {
01461 struct bitmap_array_bits_state {
01462 Bitmap *bitmap;
01463 int32 bit;
01464 } *state;
01465 FuncCallContext *funcctx;
01466 MemoryContext oldcontext;
01467 char *name;
01468 bool result;
01469 bool found;
01470 BitmapArray *bmarray;
01471 int arrayelem;
01472 Datum datum;
01473
01474 if (SRF_IS_FIRSTCALL())
01475 {
01476
01477 ensure_init();
01478
01479 funcctx = SRF_FIRSTCALL_INIT();
01480 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
01481 state = palloc(sizeof(struct bitmap_array_bits_state));
01482 MemoryContextSwitchTo(oldcontext);
01483
01484 name = strfromtext(PG_GETARG_TEXT_P(0));
01485 arrayelem = PG_GETARG_INT32(1);
01486 bmarray = GetBitmapArray(name, false);
01487
01488 if (!bmarray) {
01489 ereport(ERROR,
01490 (errcode(ERRCODE_INTERNAL_ERROR),
01491 errmsg("BitmapArray %s is not defined",
01492 name),
01493 errhint("Perhaps the name is mis-spelled, or its "
01494 "definition is missing from "
01495 "veil_init().")));
01496 }
01497
01498 state->bitmap = vl_BitmapFromArray(bmarray, arrayelem);
01499 if (!state->bitmap) {
01500 ereport(ERROR,
01501 (errcode(ERRCODE_INTERNAL_ERROR),
01502 errmsg("Bitmap Array range error (%d not in %d..%d)",
01503 arrayelem, bmarray->arrayzero, bmarray->arraymax),
01504 errdetail("Attempt to reference BitmapArray element "
01505 "outside of the BitmapArray's defined range")));
01506 }
01507
01508 state->bit = state->bitmap->bitzero;
01509 funcctx->user_fctx = state;
01510 }
01511
01512 funcctx = SRF_PERCALL_SETUP();
01513 state = funcctx->user_fctx;
01514
01515 state->bit = vl_BitmapNextBit(state->bitmap, state->bit, &found);
01516
01517 if (found) {
01518 datum = Int32GetDatum(state->bit);
01519 state->bit++;
01520 SRF_RETURN_NEXT(funcctx, datum);
01521 }
01522 else {
01523 SRF_RETURN_DONE(funcctx);
01524 }
01525 }
01526
01527 PG_FUNCTION_INFO_V1(veil_bitmap_array_arange);
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537 Datum
01538 veil_bitmap_array_arange(PG_FUNCTION_ARGS)
01539 {
01540 char *name;
01541 BitmapArray *bmarray;
01542
01543 ensure_init();
01544
01545 name = strfromtext(PG_GETARG_TEXT_P(0));
01546 bmarray = GetBitmapArray(name, false);
01547
01548 if (!bmarray) {
01549 ereport(ERROR,
01550 (errcode(ERRCODE_INTERNAL_ERROR),
01551 errmsg("BitmapArray %s is not defined",
01552 name),
01553 errhint("Perhaps the name is mis-spelled, or its "
01554 "definition is missing from veil_init().")));
01555 }
01556
01557 PG_RETURN_DATUM(datum_from_range(bmarray->arrayzero, bmarray->arraymax));
01558 }
01559
01560
01561 PG_FUNCTION_INFO_V1(veil_bitmap_array_brange);
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571 Datum
01572 veil_bitmap_array_brange(PG_FUNCTION_ARGS)
01573 {
01574 char *name;
01575 BitmapArray *bmarray;
01576
01577 ensure_init();
01578
01579 name = strfromtext(PG_GETARG_TEXT_P(0));
01580 bmarray = GetBitmapArray(name, false);
01581
01582 if (!bmarray) {
01583 ereport(ERROR,
01584 (errcode(ERRCODE_INTERNAL_ERROR),
01585 errmsg("BitmapArray %s is not defined",
01586 name),
01587 errhint("Perhaps the name is mis-spelled, or its "
01588 "definition is missing from veil_init().")));
01589 }
01590
01591 PG_RETURN_DATUM(datum_from_range(bmarray->bitzero, bmarray->bitmax));
01592 }
01593
01594
01595
01596 PG_FUNCTION_INFO_V1(veil_init_bitmap_hash);
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607 Datum
01608 veil_init_bitmap_hash(PG_FUNCTION_ARGS)
01609 {
01610 char *bmhash_name;
01611 char *range_name;
01612 VarEntry *bmhash_var;
01613 BitmapHash *bmhash;
01614 Range *range;
01615
01616 ensure_init();
01617
01618 bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
01619 bmhash_var = vl_lookup_variable(bmhash_name);
01620 bmhash = GetBitmapHashFromVar(bmhash_var, true);
01621
01622 range_name = strfromtext(PG_GETARG_TEXT_P(1));
01623 range = GetRange(range_name, false);
01624
01625 if (bmhash_var->shared) {
01626 ereport(ERROR,
01627 (errcode(ERRCODE_INTERNAL_ERROR),
01628 errmsg("illegal attempt to define shared BitmapHash %s",
01629 bmhash_name),
01630 errhint("BitmapHashes may only be defined as session, "
01631 "not shared, variables.")));
01632 }
01633 vl_NewBitmapHash(&bmhash, bmhash_name,
01634 range->min, range->max);
01635
01636 bmhash_var->obj = (Object *) bmhash;
01637
01638 PG_RETURN_BOOL(true);
01639 }
01640
01641
01642 PG_FUNCTION_INFO_V1(veil_clear_bitmap_hash);
01643
01644
01645
01646
01647
01648
01649
01650
01651 Datum
01652 veil_clear_bitmap_hash(PG_FUNCTION_ARGS)
01653 {
01654 char *bmhash_name;
01655 VarEntry *bmhash_var;
01656 BitmapHash *bmhash;
01657
01658 ensure_init();
01659
01660 bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
01661 bmhash_var = vl_lookup_variable(bmhash_name);
01662 bmhash = GetBitmapHashFromVar(bmhash_var, true);
01663
01664 vl_NewBitmapHash(&bmhash, bmhash_name,
01665 bmhash->bitzero, bmhash->bitmax);
01666
01667 bmhash_var->obj = (Object *) bmhash;
01668
01669 PG_RETURN_BOOL(true);
01670 }
01671
01672
01673 PG_FUNCTION_INFO_V1(veil_bitmap_hash_key_exists);
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685 Datum
01686 veil_bitmap_hash_key_exists(PG_FUNCTION_ARGS)
01687 {
01688 char *bmhash_name;
01689 VarEntry *bmhash_var;
01690 BitmapHash *bmhash;
01691 char *hashelem;
01692 bool found;
01693
01694 bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
01695 bmhash = GetBitmapHash(bmhash_name, false);
01696
01697 hashelem = strfromtext(PG_GETARG_TEXT_P(1));
01698
01699 found = vl_BitmapHashHasKey(bmhash, hashelem);
01700
01701 PG_RETURN_BOOL(found);
01702 }
01703
01704 PG_FUNCTION_INFO_V1(veil_bitmap_from_hash);
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718 Datum
01719 veil_bitmap_from_hash(PG_FUNCTION_ARGS)
01720 {
01721 text *bmref_text;
01722 char *bmref_name;
01723 BitmapRef *bmref;
01724 char *bmhash_name;
01725 VarEntry *bmhash_var;
01726 BitmapHash *bmhash;
01727 char *hashelem;
01728 Bitmap *bitmap;
01729
01730 bmref_text = PG_GETARG_TEXT_P(0);
01731 bmref_name = strfromtext(bmref_text);
01732 bmref = GetBitmapRef(bmref_name);
01733
01734 bmhash_name = strfromtext(PG_GETARG_TEXT_P(1));
01735 bmhash = GetBitmapHash(bmhash_name, false);
01736
01737 hashelem = strfromtext(PG_GETARG_TEXT_P(2));
01738 bitmap = vl_AddBitmapToHash(bmhash, hashelem);
01739
01740 bmref->bitmap = bitmap;
01741 bmref->xid = GetCurrentTransactionId();
01742 PG_RETURN_TEXT_P(bmref_text);
01743 }
01744
01745 PG_FUNCTION_INFO_V1(veil_bitmap_hash_testbit);
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757 Datum
01758 veil_bitmap_hash_testbit(PG_FUNCTION_ARGS)
01759 {
01760 char *name;
01761 BitmapHash *bmhash;
01762 char *hashelem;
01763 Bitmap *bitmap;
01764 int32 bit;
01765
01766 ensure_init();
01767
01768 hashelem = strfromtext(PG_GETARG_TEXT_P(1));
01769 bit = PG_GETARG_INT32(2);
01770
01771 name = strfromtext(PG_GETARG_TEXT_P(0));
01772 bmhash = GetBitmapHash(name, false);
01773
01774 bitmap = vl_BitmapFromHash(bmhash, hashelem);
01775 if (bitmap) {
01776 PG_RETURN_BOOL(vl_BitmapTestbit(bitmap, bit));
01777 }
01778 else {
01779 PG_RETURN_BOOL(false);
01780 }
01781 }
01782
01783 PG_FUNCTION_INFO_V1(veil_bitmap_hash_setbit);
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795 Datum
01796 veil_bitmap_hash_setbit(PG_FUNCTION_ARGS)
01797 {
01798 char *name;
01799 BitmapHash *bmhash;
01800 Bitmap *bitmap;
01801 char *hashelem;
01802 int32 bit;
01803
01804 ensure_init();
01805
01806 hashelem = strfromtext(PG_GETARG_TEXT_P(1));
01807 bit = PG_GETARG_INT32(2);
01808 name = strfromtext(PG_GETARG_TEXT_P(0));
01809 bmhash = GetBitmapHash(name, false);
01810
01811 bitmap = vl_AddBitmapToHash(bmhash, hashelem);
01812
01813 vl_BitmapSetbit(bitmap, bit);
01814 PG_RETURN_BOOL(true);
01815 }
01816
01817
01818 PG_FUNCTION_INFO_V1(veil_bitmap_hash_clearbit);
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830 Datum
01831 veil_bitmap_hash_clearbit(PG_FUNCTION_ARGS)
01832 {
01833 char *name;
01834 BitmapHash *bmhash;
01835 Bitmap *bitmap;
01836 char *hashelem;
01837 int32 bit;
01838
01839 ensure_init();
01840
01841 hashelem = strfromtext(PG_GETARG_TEXT_P(1));
01842 bit = PG_GETARG_INT32(2);
01843 name = strfromtext(PG_GETARG_TEXT_P(0));
01844 bmhash = GetBitmapHash(name, false);
01845
01846 bitmap = vl_AddBitmapToHash(bmhash, hashelem);
01847
01848 vl_BitmapClearbit(bitmap, bit);
01849 PG_RETURN_BOOL(true);
01850 }
01851
01852
01853 PG_FUNCTION_INFO_V1(veil_union_into_bitmap_hash);
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867 Datum
01868 veil_union_into_bitmap_hash(PG_FUNCTION_ARGS)
01869 {
01870 char *bitmap_name;
01871 char *bmhash_name;
01872 Bitmap *target;
01873 BitmapHash *bmhash;
01874 Bitmap *bitmap;
01875 char *hashelem;
01876
01877 ensure_init();
01878
01879 bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
01880 hashelem = strfromtext(PG_GETARG_TEXT_P(1));
01881
01882 bitmap_name = strfromtext(PG_GETARG_TEXT_P(2));
01883 bitmap = GetBitmap(bitmap_name, false, true);
01884 bmhash = GetBitmapHash(bmhash_name, false);
01885
01886 target = vl_AddBitmapToHash(bmhash, hashelem);
01887 if (target) {
01888 vl_BitmapUnion(target, bitmap);
01889 }
01890 PG_RETURN_BOOL(true);
01891 }
01892
01893 PG_FUNCTION_INFO_V1(veil_union_from_bitmap_hash);
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907 Datum
01908 veil_union_from_bitmap_hash(PG_FUNCTION_ARGS)
01909 {
01910 char *bitmap_name;
01911 char *bmhash_name;
01912 Bitmap *target;
01913 BitmapHash *bmhash;
01914 Bitmap *bitmap;
01915 char *hashelem;
01916
01917 ensure_init();
01918
01919 hashelem = strfromtext(PG_GETARG_TEXT_P(2));
01920
01921 bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
01922 bmhash_name = strfromtext(PG_GETARG_TEXT_P(1));
01923 target = GetBitmap(bitmap_name, false, true);
01924 bmhash = GetBitmapHash(bmhash_name, false);
01925
01926 bitmap = vl_BitmapFromHash(bmhash, hashelem);
01927 if (bitmap) {
01928 vl_BitmapUnion(target, bitmap);
01929 }
01930 PG_RETURN_BOOL(true);
01931 }
01932
01933 PG_FUNCTION_INFO_V1(veil_intersect_from_bitmap_hash);
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947 Datum
01948 veil_intersect_from_bitmap_hash(PG_FUNCTION_ARGS)
01949 {
01950 char *bitmap_name;
01951 char *bmhash_name;
01952 Bitmap *target;
01953 BitmapHash *bmhash;
01954 Bitmap *bitmap;
01955 char *hashelem;
01956
01957 ensure_init();
01958
01959 hashelem = strfromtext(PG_GETARG_TEXT_P(2));
01960
01961 bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
01962 bmhash_name = strfromtext(PG_GETARG_TEXT_P(1));
01963 target = GetBitmap(bitmap_name, false, true);
01964 bmhash = GetBitmapHash(bmhash_name, false);
01965
01966 bitmap = vl_BitmapFromHash(bmhash, hashelem);
01967 if (bitmap) {
01968 vl_BitmapIntersect(target, bitmap);
01969 }
01970 else {
01971
01972
01973 vl_ClearBitmap(target);
01974 }
01975 PG_RETURN_BOOL(true);
01976 }
01977
01978 PG_FUNCTION_INFO_V1(veil_bitmap_hash_bits);
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989 Datum
01990 veil_bitmap_hash_bits(PG_FUNCTION_ARGS)
01991 {
01992 struct bitmap_hash_bits_state {
01993 Bitmap *bitmap;
01994 int32 bit;
01995 } *state;
01996 FuncCallContext *funcctx;
01997 MemoryContext oldcontext;
01998 char *name;
01999 bool result;
02000 bool found;
02001 BitmapHash *bmhash;
02002 char *hashelem;
02003 Datum datum;
02004
02005 if (SRF_IS_FIRSTCALL())
02006 {
02007
02008 ensure_init();
02009
02010 funcctx = SRF_FIRSTCALL_INIT();
02011 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
02012 state = palloc(sizeof(struct bitmap_hash_bits_state));
02013 MemoryContextSwitchTo(oldcontext);
02014
02015 name = strfromtext(PG_GETARG_TEXT_P(0));
02016 hashelem = strfromtext(PG_GETARG_TEXT_P(1));
02017 bmhash = GetBitmapHash(name, false);
02018
02019 if (!bmhash) {
02020 ereport(ERROR,
02021 (errcode(ERRCODE_INTERNAL_ERROR),
02022 errmsg("Bitmap Hash %s not defined", name)));
02023 }
02024
02025 state->bitmap = vl_BitmapFromHash(bmhash, hashelem);
02026 if (!state->bitmap) {
02027 SRF_RETURN_DONE(funcctx);
02028 }
02029
02030 state->bit = state->bitmap->bitzero;
02031 funcctx->user_fctx = state;
02032 }
02033
02034 funcctx = SRF_PERCALL_SETUP();
02035 state = funcctx->user_fctx;
02036
02037 state->bit = vl_BitmapNextBit(state->bitmap, state->bit, &found);
02038
02039 if (found) {
02040 datum = Int32GetDatum(state->bit);
02041 state->bit++;
02042 SRF_RETURN_NEXT(funcctx, datum);
02043 }
02044 else {
02045 SRF_RETURN_DONE(funcctx);
02046 }
02047 }
02048
02049 PG_FUNCTION_INFO_V1(veil_bitmap_hash_range);
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059 Datum
02060 veil_bitmap_hash_range(PG_FUNCTION_ARGS)
02061 {
02062 char *name;
02063 BitmapHash *bmhash;
02064
02065 ensure_init();
02066
02067 name = strfromtext(PG_GETARG_TEXT_P(0));
02068 bmhash = GetBitmapHash(name, false);
02069
02070 if (!bmhash) {
02071 ereport(ERROR,
02072 (errcode(ERRCODE_INTERNAL_ERROR),
02073 errmsg("Bitmap Hash %s not defined", name)));
02074 }
02075
02076 PG_RETURN_DATUM(datum_from_range(bmhash->bitzero, bmhash->bitmax));
02077 }
02078
02079
02080 PG_FUNCTION_INFO_V1(veil_bitmap_hash_entries);
02081
02082
02083
02084
02085
02086
02087
02088 Datum
02089 veil_bitmap_hash_entries(PG_FUNCTION_ARGS)
02090 {
02091 struct bitmap_hash_entries_state {
02092 BitmapHash *bmhash;
02093 VarEntry *var;
02094 } *state;
02095 FuncCallContext *funcctx;
02096 MemoryContext oldcontext;
02097 char *name;
02098 char *hashelem;
02099 Datum datum;
02100 text *result;
02101
02102 if (SRF_IS_FIRSTCALL())
02103 {
02104
02105 ensure_init();
02106
02107 funcctx = SRF_FIRSTCALL_INIT();
02108 oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
02109 state = palloc(sizeof(struct bitmap_hash_entries_state));
02110 MemoryContextSwitchTo(oldcontext);
02111
02112 name = strfromtext(PG_GETARG_TEXT_P(0));
02113 state->bmhash = GetBitmapHash(name, false);
02114
02115 if (!state->bmhash) {
02116 ereport(ERROR,
02117 (errcode(ERRCODE_INTERNAL_ERROR),
02118 errmsg("Bitmap Hash %s not defined", name)));
02119 }
02120
02121 state->var = NULL;
02122 funcctx->user_fctx = state;
02123 }
02124
02125 funcctx = SRF_PERCALL_SETUP();
02126 state = funcctx->user_fctx;
02127
02128 state->var = vl_NextHashEntry(state->bmhash->hash, state->var);
02129
02130 if (state->var) {
02131 result = textfromstrn(state->var->key, HASH_KEYLEN);
02132 datum = PointerGetDatum(result);
02133 SRF_RETURN_NEXT(funcctx, datum);
02134 }
02135 else {
02136 SRF_RETURN_DONE(funcctx);
02137 }
02138 }
02139
02140
02141 PG_FUNCTION_INFO_V1(veil_bitmap_hash_defined);
02142
02143
02144
02145
02146
02147
02148
02149
02150 Datum
02151 veil_bitmap_hash_defined(PG_FUNCTION_ARGS)
02152 {
02153 char *bmhash_name;
02154 BitmapHash *bmhash;
02155 char *hashelem;
02156 Bitmap *bitmap;
02157
02158 ensure_init();
02159
02160
02161 bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
02162 hashelem = strfromtext(PG_GETARG_TEXT_P(1));
02163 bmhash = GetBitmapHash(bmhash_name, false);
02164
02165 bitmap = vl_BitmapFromHash(bmhash, hashelem);
02166 PG_RETURN_BOOL(bitmap != NULL);
02167 }
02168
02169
02170 PG_FUNCTION_INFO_V1(veil_int4_set);
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181 Datum
02182 veil_int4_set(PG_FUNCTION_ARGS)
02183 {
02184 char *name;
02185 Int4Var *var;
02186 int32 value;
02187
02188 ensure_init();
02189
02190 if (PG_ARGISNULL(0)) {
02191 PG_RETURN_NULL();
02192 }
02193
02194 name = strfromtext(PG_GETARG_TEXT_P(0));
02195 var = GetInt4Var(name, true);
02196
02197 if (PG_ARGISNULL(1)) {
02198 var->isnull = true;
02199 PG_RETURN_NULL();
02200 }
02201 else {
02202 value = PG_GETARG_INT32(1);
02203 var->isnull = false;
02204 var->value = value;
02205 PG_RETURN_INT32(value);
02206 }
02207 }
02208
02209 PG_FUNCTION_INFO_V1(veil_int4_get);
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219 Datum
02220 veil_int4_get(PG_FUNCTION_ARGS)
02221 {
02222 char *name;
02223 Int4Var *var;
02224 int32 value;
02225
02226 ensure_init();
02227
02228 name = strfromtext(PG_GETARG_TEXT_P(0));
02229 var = GetInt4Var(name, true);
02230
02231 if (var->isnull) {
02232 PG_RETURN_NULL();
02233 }
02234 else {
02235 PG_RETURN_INT32(var->value);
02236 }
02237 }
02238
02239 PG_FUNCTION_INFO_V1(veil_init_int4array);
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250 Datum
02251 veil_init_int4array(PG_FUNCTION_ARGS)
02252 {
02253 char *array_name;
02254 char *range_name;
02255 VarEntry *array_var;
02256 VarEntry *range_var;
02257 Int4Array *array;
02258 Range *range;
02259
02260 ensure_init();
02261
02262 array_name = strfromtext(PG_GETARG_TEXT_P(0));
02263 array_var = vl_lookup_variable(array_name);
02264 array = GetInt4ArrayFromVar(array_var, true);
02265
02266 range_name = strfromtext(PG_GETARG_TEXT_P(1));
02267 range = GetRange(range_name, false);
02268
02269 array = vl_NewInt4Array(array, array_var->shared, range->min, range->max);
02270 array_var->obj = (Object *) array;
02271
02272 PG_RETURN_BOOL(true);
02273 }
02274
02275 PG_FUNCTION_INFO_V1(veil_clear_int4array);
02276
02277
02278
02279
02280
02281
02282
02283
02284 Datum
02285 veil_clear_int4array(PG_FUNCTION_ARGS)
02286 {
02287 char *array_name;
02288 Int4Array *array;
02289
02290 ensure_init();
02291
02292 array_name = strfromtext(PG_GETARG_TEXT_P(0));
02293 array = GetInt4Array(array_name, false);
02294
02295 vl_ClearInt4Array(array);
02296
02297 PG_RETURN_BOOL(true);
02298 }
02299
02300 PG_FUNCTION_INFO_V1(veil_int4array_set);
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310 Datum
02311 veil_int4array_set(PG_FUNCTION_ARGS)
02312 {
02313 char *array_name;
02314 Int4Array *array;
02315 int32 idx;
02316 int32 value;
02317
02318 ensure_init();
02319
02320 array_name = strfromtext(PG_GETARG_TEXT_P(0));
02321 array = GetInt4Array(array_name, false);
02322 idx = PG_GETARG_INT32(1);
02323 value = PG_GETARG_INT32(2);
02324 vl_Int4ArraySet(array, idx, value);
02325
02326 PG_RETURN_INT32(value);
02327 }
02328
02329 PG_FUNCTION_INFO_V1(veil_int4array_get);
02330
02331
02332
02333
02334
02335
02336
02337
02338 Datum
02339 veil_int4array_get(PG_FUNCTION_ARGS)
02340 {
02341 char *array_name;
02342 Int4Array *array;
02343 int32 idx;
02344 int32 value;
02345
02346 ensure_init();
02347
02348 array_name = strfromtext(PG_GETARG_TEXT_P(0));
02349 array = GetInt4Array(array_name, false);
02350 idx = PG_GETARG_INT32(1);
02351 value = vl_Int4ArrayGet(array, idx);
02352
02353 PG_RETURN_INT32(value);
02354 }
02355
02356
02357 PG_FUNCTION_INFO_V1(veil_init);
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371 Datum
02372 veil_init(PG_FUNCTION_ARGS)
02373 {
02374 ereport(ERROR,
02375 (errcode(ERRCODE_INTERNAL_ERROR),
02376 errmsg("default veil version of veil_init() has been called"),
02377 errhint("You must define your own version of this function.")));
02378
02379 PG_RETURN_BOOL(true);
02380 }
02381
02382 PG_FUNCTION_INFO_V1(veil_perform_reset);
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396 Datum
02397 veil_perform_reset(PG_FUNCTION_ARGS)
02398 {
02399 bool success = true;
02400 bool result;
02401 int ok;
02402
02403 ensure_init();
02404 ok = vl_spi_connect();
02405 if (ok != SPI_OK_CONNECT) {
02406 ereport(ERROR,
02407 (errcode(ERRCODE_INTERNAL_ERROR),
02408 errmsg("failed to perform reset"),
02409 errdetail("SPI_connect() failed, returning %d.", ok)));
02410 }
02411
02412 success = vl_prepare_context_switch();
02413 if (success) {
02414 result = vl_bool_from_query("select veil_init(TRUE)", &success);
02415 elog(NOTICE, "veil_init returns %s to veil_perform_reset",
02416 result? "true": "false");
02417 success = vl_complete_context_switch();
02418 elog(NOTICE,
02419 "vl_complete_context_switch returns %s to veil_perform_reset",
02420 success? "true": "false");
02421 success &= result;
02422 }
02423 else {
02424 ereport(WARNING,
02425 (errcode(ERRCODE_INTERNAL_ERROR),
02426 errmsg("failed to perform reset"),
02427 errdetail("Unable to prepare for memory reset. "
02428 "Maybe another process is performing a reset, "
02429 "or maybe there is a long-running transaction that "
02430 "is still using the previous memory context.")));
02431 }
02432
02433 ok = vl_spi_finish();
02434 PG_RETURN_BOOL(success);
02435 }
02436
02437 PG_FUNCTION_INFO_V1(veil_force_reset);
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451 Datum
02452 veil_force_reset(PG_FUNCTION_ARGS)
02453 {
02454 ensure_init();
02455 vl_force_context_switch();
02456 PG_RETURN_BOOL(true);
02457 }
02458
02459
02460 PG_FUNCTION_INFO_V1(veil_version);
02461
02462
02463
02464
02465
02466
02467
02468 Datum
02469 veil_version(PG_FUNCTION_ARGS)
02470 {
02471 char *version_str;
02472 text *version_text;
02473
02474 version_str = palloc(sizeof(char) * strlen(VEIL_VERSION) +
02475 strlen(VEIL_VERSION_INFO) + 4);
02476 sprintf(version_str, "%s (%s)", VEIL_VERSION, VEIL_VERSION_INFO);
02477
02478 version_text = textfromstr(version_str);
02479 PG_RETURN_TEXT_P(version_text);
02480 }
02481
02482 PG_FUNCTION_INFO_V1(veil_serialise);
02483
02484
02485
02486
02487
02488
02489
02490
02491 Datum
02492 veil_serialise(PG_FUNCTION_ARGS)
02493 {
02494 char *name;
02495 char *result;
02496
02497 ensure_init();
02498
02499 if (PG_ARGISNULL(0)) {
02500 PG_RETURN_NULL();
02501 }
02502
02503 name = strfromtext(PG_GETARG_TEXT_P(0));
02504 result = vl_serialise_var(name);
02505
02506 if (result) {
02507 PG_RETURN_TEXT_P(textfromstr(result));
02508 }
02509 else {
02510 PG_RETURN_NULL();
02511 }
02512 }
02513
02514
02515 PG_FUNCTION_INFO_V1(veil_deserialise);
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526 Datum
02527 veil_deserialise(PG_FUNCTION_ARGS)
02528 {
02529 char *stream;
02530 int4 result;
02531 text *txt;
02532
02533 ensure_init();
02534
02535 if (PG_ARGISNULL(0)) {
02536 PG_RETURN_NULL();
02537 }
02538
02539 txt = PG_GETARG_TEXT_P(0);
02540 stream = strfromtext(txt);
02541 result = vl_deserialise(&stream);
02542
02543 PG_RETURN_INT32(result);
02544 }
02545
02546