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