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