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