Veil
veil_interface.c
Go to the documentation of this file.
1 /**
2  * @file veil_interface.c
3  * \code
4  * Author: Marc Munro
5  * Copyright (c) 2005 - 2012 Marc Munro
6  * License: BSD
7  *
8  * \endcode
9  * @brief
10  * Functions providing the SQL interface to veil, and utility functions
11  * to support them.
12  */
13 
14 #include "postgres.h"
15 #include "access/xact.h"
16 #include "executor/spi.h"
17 #include "funcapi.h"
18 #include "utils/hsearch.h"
19 #include "utils/memutils.h"
20 
21 #include "veil_version.h"
22 #include "veil_funcs.h"
23 #include "veil_datatypes.h"
24 
25 
26 PG_MODULE_MAGIC;
27 
28 
29 /**
30  * Create a dynamically allocated C string as a copy of a text value.
31  *
32  * @param in text value from which the copy is made.
33  * @return Dynamically allocated (by palloc()) copy of in.
34  */
35 static char *
36 strfromtext(text *in)
37 {
38  char *out = palloc(VARSIZE(in) - VARHDRSZ + 1);
39  memcpy(out, VARDATA(in), VARSIZE(in) - VARHDRSZ);
40  out[VARSIZE(in) - VARHDRSZ] = '\0';
41 
42  return out;
43 }
44 
45 /**
46  * Create a dynamically allocated text value as a copy of a C string.
47  *
48  * @param in String to be copied
49  * @return Dynamically allocated (by palloc()) copy of in.
50  */
51 static text *
52 textfromstr(char *in)
53 {
54  int len = strlen(in);
55  text *out = palloc(len + VARHDRSZ);
56  memcpy(VARDATA(out), in, len);
57  SET_VARSIZE(out, (len + VARHDRSZ));
58 
59  return out;
60 }
61 
62 /**
63  * Create a dynamically allocated text value as a copy of a C string,
64  * applying a limit to the length.
65  *
66  * @param in String to be copied
67  * @param limit Maximum length of string to be copied.
68  * @return Dynamically allocated (by palloc()) copy of in.
69  */
70 static text *
71 textfromstrn(char *in, int limit)
72 {
73  int len = strlen(in);
74  text *out;
75 
76  if (limit < len) {
77  len = limit;
78  }
79 
80  out = palloc(len + VARHDRSZ);
81  memcpy(VARDATA(out), in, len);
82  SET_VARSIZE(out, (len + VARHDRSZ));
83 
84  return out;
85 }
86 
87 /**
88  * Create a dynamically allocated text value as a copy of a C string,
89  * applying a limit to the length.
90  *
91  * @param str String to be copied
92  * @return Dynamically allocated (by palloc()) copy of str.
93  */
94 static char *
95 copystr(char *str)
96 {
97  char *new = palloc((sizeof(char) * strlen(str) + 1));
98  strcpy(new, str);
99  return new;
100 }
101 
102 /**
103  * Create a dynamically allocated C string as a copy of an integer value.
104  *
105  * @param val value to be stringified
106  * @return Dynamically allocated string.
107  */
108 static char *
109 strfromint(int32 val)
110 {
111  char *new = palloc((sizeof(char) * 17)); /* Large enough for any 32
112  * bit number */
113  sprintf(new, "%d", val);
114  return new;
115 }
116 
117 /**
118  * Create a dynamically allocated C string as a copy of a boolean value.
119  *
120  * @param val value to be stringified
121  * @return Dynamically allocated string.
122  */
123 static char *
124 strfrombool(bool val)
125 {
126  char *new = palloc((sizeof(char) * 2));
127  if (val) {
128  strcpy(new, "t");
129  }
130  else {
131  strcpy(new, "f");
132  }
133  return new;
134 }
135 
136 /**
137  * Perform session initialisation once for the session. This calls the
138  * user-defined function veil_init which should create and possibly
139  * initialise all session and, maybe, shared variables. This function
140  * may be safely called any number of times - it will only perform the
141  * initialisation on the first call.
142  *
143  */
144 static void
146 {
147  bool success = false;
148  TransactionId this_xid;
149  int ok;
150  bool pushed;
151  static bool done = false;
152  static TransactionId xid = 0;
153 
154  if (!done) {
155  this_xid = GetCurrentTransactionId();
156  if (xid == this_xid) {
157  /* We must have been called recursively, so just return */
158  return;
159  }
160  xid = this_xid; /* Record our xid in case we recurse */
161  ok = vl_spi_connect(&pushed);
162  if (ok != SPI_OK_CONNECT) {
163  ereport(ERROR,
164  (errcode(ERRCODE_INTERNAL_ERROR),
165  errmsg("failed to initialise session (1)"),
166  errdetail("SPI_connect() failed, returning %d.", ok)));
167  }
168 
169  (void) vl_get_shared_hash(); /* Init all shared memory constructs */
170  (void) vl_bool_from_query("select veil.veil_init(FALSE)", &success);
171 
172  if (!success) {
173  ereport(ERROR,
174  (errcode(ERRCODE_INTERNAL_ERROR),
175  errmsg("failed to initialise session (2)"),
176  errdetail("veil_init() did not return true.")));
177  }
178 
179  ok = vl_spi_finish(pushed);
180  if (ok != SPI_OK_FINISH) {
181  ereport(ERROR,
182  (errcode(ERRCODE_INTERNAL_ERROR),
183  errmsg("failed to initialise session (3)"),
184  errdetail("SPI_finish() failed, returning %d.", ok)));
185  }
186  done = true; /* init is done, we don't need to do it again. */
187  }
188 }
189 
190 /**
191  * Report, by raising an error, a type mismatch between the expected and
192  * actual type of a VarEntry variable.
193  *
194  * @param name The name of the variable
195  * @param expected The expected type.
196  * @param got The actual type
197  */
198 extern void
199 vl_type_mismatch(char *name,
200  ObjType expected,
201  ObjType got)
202 {
203  ereport(ERROR,
204  (errcode(ERRCODE_INTERNAL_ERROR),
205  errmsg("type mismatch in %s: expected %s, got %s",
206  name, vl_ObjTypeName(expected), vl_ObjTypeName(got)),
207  errdetail("Variable %s is not of the expected type.", name)));
208 }
209 
210 /**
211  * Return the Int4Var variable matching the name parameter, possibly
212  * creating the variable. Raise an error if the named variable already
213  * exists and is of the wrong type.
214  *
215  * @param name The name of the variable.
216  * @param create Whether to create the variable if it does not exist.
217  * @return Pointer to the variable or null if the variable does not
218  * exist and create was false.
219  */
220 static Int4Var *
221 GetInt4Var(char *name,
222  bool create)
223 {
224  VarEntry *var;
225  Int4Var *i4v;
226 
227  var = vl_lookup_variable(name);
228  i4v = (Int4Var *) var->obj;
229 
230  if (i4v) {
231  if (i4v->type != OBJ_INT4) {
232  vl_type_mismatch(name, OBJ_INT4, i4v->type);
233  }
234  }
235  else {
236  if (create) {
237  var->obj = (Object *) vl_NewInt4(var->shared);
238  i4v = (Int4Var *) var->obj;
239  }
240  else {
241  vl_type_mismatch(name, OBJ_INT4, OBJ_UNDEFINED);
242  }
243  }
244  return i4v;
245 }
246 
247 /**
248  * Return the Range variable matching the name parameter, possibly
249  * creating the variable. Raise an error if the named variable already
250  * exists and is of the wrong type.
251  *
252  * @param name The name of the variable.
253  * @param create Whether to create the variable if it does not exist.
254  * @return Pointer to the variable or null if the variable does not
255  * exist and create was false.
256  */
257 static Range *
258 GetRange(char *name,
259  bool create)
260 {
261  VarEntry *var;
262  Range *range;
263 
264  var = vl_lookup_variable(name);
265  range = (Range *) var->obj;
266 
267  if (range) {
268  if (range->type != OBJ_RANGE) {
269  vl_type_mismatch(name, OBJ_RANGE, range->type);
270  }
271  }
272  else {
273  if (create) {
274  var->obj = (Object *) vl_NewRange(var->shared);
275  range = (Range *) var->obj;
276  }
277  else {
278  vl_type_mismatch(name, OBJ_RANGE, OBJ_UNDEFINED);
279  }
280  }
281  return range;
282 }
283 
284 /**
285  * Return the Bitmap from a bitmap variable. This function exists
286  * primarily to perform type checking, and to raise an error if the
287  * variable is not a bitmap.
288  *
289  * @param var The VarEntry that should contain a bitmap.
290  * @param allow_empty Whether to raise an error if the variable has not
291  * yet been initialised.
292  * @param allow_ref Whether to (not) raise an error if the variable is a
293  * bitmap_ref rather than a bitmap.
294  * @return Pointer to the variable or null if the variable is undefined
295  * and allow_empty was true.
296  */
297 static Bitmap *
299  bool allow_empty,
300  bool allow_ref)
301 {
302  Bitmap *bitmap = (Bitmap *) var->obj;
303 
304  if (bitmap) {
305  if (bitmap->type != OBJ_BITMAP) {
306  if (allow_ref && (bitmap->type == OBJ_BITMAP_REF)) {
307  BitmapRef *bmref = (BitmapRef *) bitmap;
308  if (bmref->xid == GetCurrentTransactionId()) {
309  bitmap = bmref->bitmap;
310  }
311  else {
312  ereport(ERROR,
313  (errcode(ERRCODE_INTERNAL_ERROR),
314  errmsg("BitmapRef %s is not defined",
315  var->key),
316  errhint("Perhaps the name is mis-spelled, or its "
317  "definition is missing from "
318  "veil_init().")));
319  }
320  }
321  else {
322  vl_type_mismatch(var->key, OBJ_BITMAP, bitmap->type);
323  }
324  }
325  }
326  if (!bitmap) {
327  if (!allow_empty) {
328  vl_type_mismatch(var->key, OBJ_BITMAP, OBJ_UNDEFINED);
329  }
330  }
331  return bitmap;
332 }
333 
334 /**
335  * Return the Bitmap matching the name parameter, possibly creating the
336  * VarEntry (variable) for it. Raise an error if the named variable
337  * already exists and is of the wrong type.
338  *
339  * @param name The name of the variable.
340  * @param allow_empty Whether to raise an error if the variable has not
341  * been defined.
342  * @param allow_ref Whether to (not) raise an error if the variable is a
343  * bitmap_ref rather than a bitmap.
344  * @return Pointer to the variable or null if the variable does not
345  * exist and allow_empty was false.
346  */
347 static Bitmap *
348 GetBitmap(char *name,
349  bool allow_empty,
350  bool allow_ref)
351 {
352  VarEntry *var;
353  Bitmap *bitmap;
354 
355  var = vl_lookup_variable(name);
356  bitmap = GetBitmapFromVar(var, allow_empty, allow_ref);
357 
358  return bitmap;
359 }
360 
361 /**
362  * Return the BitmapRef from a bitmap ref variable. This function exists
363  * primarily to perform type checking, and to raise an error if the
364  * variable is not a bitmap ref. Note that BitmapRef variables may not
365  * be shared as they can contain references to non-shared objects.
366  *
367  * @param var The VarEntry that should contain a bitmap ref.
368  * @return Pointer to the variable.
369  */
370 static BitmapRef *
372 {
373  BitmapRef *bmref = (BitmapRef *) var->obj;
374 
375  if (bmref) {
376  if (bmref->type != OBJ_BITMAP_REF) {
377  vl_type_mismatch(var->key, OBJ_BITMAP_REF, bmref->type);
378  }
379  }
380  else {
381  if (var->shared) {
382  ereport(ERROR,
383  (errcode(ERRCODE_INTERNAL_ERROR),
384  errmsg("illegal attempt to define shared BitmapRef %s",
385  var->key),
386  errhint("BitmapRefs may only be defined as session, "
387  "not shared, variables.")));
388  }
389  /* Create a new bmref (these are always session variables. */
390  bmref = vl_malloc(sizeof(BitmapRef));
391  bmref->type = OBJ_BITMAP_REF;
392  bmref->bitmap = NULL;
393  var->obj = (Object *) bmref;
394  }
395 
396  return bmref;
397 }
398 
399 /**
400  * Return the BitmapRef matching the name parameter, possibly creating the
401  * VarEntry (variable) for it. Raise an error if the named variable
402  * already exists and is of the wrong type.
403  *
404  * @param name The name of the variable.
405  * @return Pointer to the variable
406  */
407 static BitmapRef *
408 GetBitmapRef(char *name)
409 {
410  VarEntry *var;
411  BitmapRef *bmref;
412 
413  var = vl_lookup_variable(name);
414  bmref = GetBitmapRefFromVar(var);
415 
416  return bmref;
417 }
418 
419 /**
420  * Return the BitmapArray from a bitmap array variable. This function
421  * exists primarily to perform type checking, and to raise an error if
422  * the variable is not a bitmap array.
423  *
424  * @param var The VarEntry that should contain a bitmap array.
425  * @param allow_empty Whether to raise an error if the variable has not
426  * yet been initialised.
427  * @return Pointer to the variable or null if the variable is undefined
428  * and allow_empty was true.
429  */
430 static BitmapArray *
432  bool allow_empty)
433 {
434  BitmapArray *bmarray;
435  bmarray = (BitmapArray *) var->obj;
436 
437  if (bmarray) {
438  if (bmarray->type != OBJ_BITMAP_ARRAY) {
439  vl_type_mismatch(var->key, OBJ_BITMAP_ARRAY, bmarray->type);
440  }
441  }
442  else {
443  if (!allow_empty) {
444  vl_type_mismatch(var->key, OBJ_BITMAP_ARRAY, OBJ_UNDEFINED);
445  }
446  }
447 
448  return bmarray;
449 }
450 
451 /**
452  * Return the BitmapArray matching the name parameter, possibly creating
453  * the (VarEntry) variable. Raise an error if the named variable
454  * already exists and is of the wrong type.
455  *
456  * @param name The name of the variable.
457  * @param allow_empty Whether to raise an error if the variable has not
458  * been defined
459  * @return Pointer to the variable or null if the variable does not
460  * exist and create was false.
461  */
462 static BitmapArray *
463 GetBitmapArray(char *name,
464  bool allow_empty)
465 {
466  VarEntry *var;
467  BitmapArray *bmarray;
468 
469  var = vl_lookup_variable(name);
470  bmarray = GetBitmapArrayFromVar(var, allow_empty);
471 
472  return bmarray;
473 }
474 
475 /**
476  * Return the BitmapHash from a bitmap hash variable. This function
477  * exists primarily to perform type checking, and to raise an error if
478  * the variable is not a bitmap hash.
479  *
480  * @param var The VarEntry that should contain a bitmap hash.
481  * @param allow_empty Whether to raise an error if the variable has not
482  * yet been initialised.
483  * @return Pointer to the variable or null if the variable is undefined
484  * and allow_empty was true.
485  */
486 static BitmapHash *
488  bool allow_empty)
489 {
490  BitmapHash *bmhash;
491  bmhash = (BitmapHash *) var->obj;
492 
493  if (bmhash) {
494  if (bmhash->type != OBJ_BITMAP_HASH) {
495  vl_type_mismatch(var->key, OBJ_BITMAP_HASH, bmhash->type);
496  }
497  }
498  else {
499  if (!allow_empty) {
500  vl_type_mismatch(var->key, OBJ_BITMAP_HASH, OBJ_UNDEFINED);
501  }
502  }
503 
504  return bmhash;
505 }
506 
507 /**
508  * Return the BitmapHash matching the name parameter, possibly creating
509  * the VarEntry (variable) for it. Raise an error if the named variable
510  * already exists and is of the wrong type.
511  *
512  * @param name The name of the variable.
513  * @param allow_empty Whether to raise an error if the variable has not
514  * been defined.
515  * @return Pointer to the variable or null if the variable does not
516  * exist and create was false.
517  */
518 static BitmapHash *
519 GetBitmapHash(char *name,
520  bool allow_empty)
521 {
522  VarEntry *var;
523  BitmapHash *bmhash;
524 
525  var = vl_lookup_variable(name);
526  bmhash = GetBitmapHashFromVar(var, allow_empty);
527 
528  return bmhash;
529 }
530 
531 /**
532  * Return the Int4Array from an Int4Array variable. This function
533  * exists primarily to perform type checking, and to raise an error if
534  * the variable is not an Int4Array.
535  *
536  * @param var The VarEntry that should contain an Int4Array.
537  * @param allow_empty Whether to raise an error if the variable has not
538  * yet been initialised.
539  * @return Pointer to the variable or null if the variable is undefined
540  * and allow_empty was true.
541  */
542 static Int4Array *
544  bool allow_empty)
545 {
546  Int4Array *array;
547  array = (Int4Array *) var->obj;
548 
549  if (array) {
550  if (array->type != OBJ_INT4_ARRAY) {
551  vl_type_mismatch(var->key, OBJ_INT4_ARRAY, array->type);
552  }
553  }
554  else {
555  if (!allow_empty) {
556  vl_type_mismatch(var->key, OBJ_INT4_ARRAY, OBJ_UNDEFINED);
557  }
558  }
559 
560  return array;
561 }
562 
563 /**
564  * Return the Int4Array matching the name parameter, possibly creating
565  * the VarEntry (variable) for it. Raise an error if the named variable
566  * already exists and is of the wrong type.
567  *
568  * @param name The name of the variable.
569  * @param allow_empty Whether to raise an error if the variable has not
570  * been defined.
571  * @return Pointer to the variable or null if the variable does not
572  * exist and create was false.
573  */
574 static Int4Array *
575 GetInt4Array(char *name,
576  bool allow_empty)
577 {
578  VarEntry *var;
579  Int4Array *array;
580 
581  var = vl_lookup_variable(name);
582  array = GetInt4ArrayFromVar(var, allow_empty);
583 
584  return array;
585 }
586 
587 PG_FUNCTION_INFO_V1(veil_variables);
588 /**
589  * <code>veil_variables() returns setof veil_variable_t</code>
590  * Return a <code>veil_variable_t</code> record for each defined
591  * variable. This includes both session and shared variables.
592  *
593  * @param fcinfo None
594  * @return <code>setof veil_variable_t</code>
595  */
596 Datum
597 veil_variables(PG_FUNCTION_ARGS)
598 {
599  TupleDesc tupdesc;
600  TupleTableSlot *slot;
601  AttInMetadata *attinmeta;
602  FuncCallContext *funcctx;
603 
604  veil_variable_t *var;
605  char **values;
606  HeapTuple tuple;
607  Datum datum;
608 
609  if (SRF_IS_FIRSTCALL())
610  {
611  /* Only do this on first call for this result set */
612  MemoryContext oldcontext;
613 
614  ensure_init();
615  funcctx = SRF_FIRSTCALL_INIT();
616  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
617 
618  tupdesc = RelationNameGetTupleDesc("veil.veil_variable_t");
619  slot = TupleDescGetSlot(tupdesc);
620  funcctx->slot = slot;
621  attinmeta = TupleDescGetAttInMetadata(tupdesc);
622  funcctx->attinmeta = attinmeta;
623 
624  MemoryContextSwitchTo(oldcontext);
625  funcctx->user_fctx = NULL;
626  }
627 
628  funcctx = SRF_PERCALL_SETUP();
629  var = vl_next_variable(funcctx->user_fctx);
630  funcctx->user_fctx = var;
631 
632  if (var) {
633  values = (char **) palloc(3 * sizeof(char *));
634  values[0] = copystr(var->name);
635  values[1] = copystr(var->type);
636  values[2] = strfrombool(var->shared);
637 
638  slot = funcctx->slot;
639  attinmeta = funcctx->attinmeta;
640 
641  tuple = BuildTupleFromCStrings(attinmeta, values);
642  datum = TupleGetDatum(slot, tuple);
643  SRF_RETURN_NEXT(funcctx, datum);
644 
645  }
646  else {
647  SRF_RETURN_DONE(funcctx);
648  }
649 }
650 
651 PG_FUNCTION_INFO_V1(veil_share);
652 /**
653  * <code>veil_share(name text) returns bool</code>
654  * Define a shared variable called NAME, returning true. If the
655  * variable is already defined as a session variable an ERROR will be
656  * raised.
657  *
658  * Session variables are simply defined by their first usage. Shared
659  * variables must be defined using this function. They may then be used
660  * in exactly the same way as session variables. Shared variables are
661  * shared by all backends and so need only be initialised once. The
662  * result of this function tells the caller whether the variable needs
663  * to be initialised. The caller that first defines a shared variable
664  * will get a false result and from this will know that the variable
665  * must be initialised. All subsequent callers will get a true result
666  * and so will know that the variable is already initialised.
667  *
668  * @param fcinfo <code>name text</code> name of variable.
669  * @return <code>bool</code> true if the variable already exists
670  */
671 Datum
672 veil_share(PG_FUNCTION_ARGS)
673 {
674  char *name;
675  VarEntry *var;
676 
677  ensure_init();
678  name = strfromtext(PG_GETARG_TEXT_P(0));
679 
680  var = vl_lookup_shared_variable(name);
681 
682  PG_RETURN_BOOL((var->obj != NULL));
683 }
684 
685 
686 PG_FUNCTION_INFO_V1(veil_init_range);
687 /**
688  * veil_init_range(name text, min int4, max int4) returns int4
689  * Initialise a Range variable called NAME constrained by MIN and MAX,
690  * returning the number of elements in the range. Ranges may be
691  * examined using the veil_range() function.
692  *
693  * @param fcinfo <code>name text</code> The name of the variable to
694  * initialise.
695  * <br><code>min int4</code> The min value of the range.
696  * <br><code>max int4</code> The max value of the range.
697  * @return <code>int4</code> The size of the range ((max - min) + 1).
698  */
699 Datum
700 veil_init_range(PG_FUNCTION_ARGS)
701 {
702  int64 min;
703  int64 max;
704  Range *range;
705  char *name;
706 
707  ensure_init();
708  name = strfromtext(PG_GETARG_TEXT_P(0));
709  min = PG_GETARG_INT32(1);
710  max = PG_GETARG_INT32(2);
711 
712  range = GetRange(name, true);
713 
714  range->min = min;
715  range->max = max;
716  PG_RETURN_INT32(max + 1 - min);
717 }
718 
719 
720 /**
721  * Create a datum containing the values of a veil_range_t composite
722  * type.
723  *
724  * @param min Min value of range
725  * @param max Max value of range
726  * @return Composite (row) type datum containing the range elements.
727  */
728 static Datum
729 datum_from_range(int64 min, int64 max)
730 {
731  static bool init_done = false;
732  static TupleDesc tupdesc;
733  static AttInMetadata *attinmeta;
734  __attribute__ ((unused)) TupleTableSlot *slot;
735  HeapTuple tuple;
736  char **values;
737 
738  if (!init_done) {
739  /* Keep all static data in top memory context where it will
740  * safely remain during the session. */
741 
742  MemoryContext oldcontext = MemoryContextSwitchTo(TopMemoryContext);
743 
744  init_done = true;
745  tupdesc = RelationNameGetTupleDesc("veil.veil_range_t");
746  slot = TupleDescGetSlot(tupdesc);
747  attinmeta = TupleDescGetAttInMetadata(tupdesc);
748 
749  MemoryContextSwitchTo(oldcontext);
750  }
751 
752  /* Create value strings to be returned to caller. */
753  values = (char **) palloc(2 * sizeof(char *));
754  values[0] = strfromint(min);
755  values[1] = strfromint(max);
756 
757  tuple = BuildTupleFromCStrings(attinmeta, values);
758  slot = TupleDescGetSlot(tupdesc);
759 
760  /* make the tuple into a datum - this seems to use slot, so any
761  * compiler warning about slot being unused would seem to be
762  * spurious. Most odd. */
763  return TupleGetDatum(slot, tuple);
764 }
765 
766 
767 PG_FUNCTION_INFO_V1(veil_range);
768 /**
769  * <code>veil_range(name text) returns veil_range_t</code>
770  * Return the range (as a SQL veil_range_t composite type) from the
771  * named variable.
772  * An Error will be raised if the variable is not defined or is of the
773  * wrong type.
774  *
775  * @param fcinfo <code>name text</code> The name of the range variable.
776  * @return <code>veil_range_t</code> Composite type containing the min
777  * and max values from the named variable.
778  */
779 Datum
780 veil_range(PG_FUNCTION_ARGS)
781 {
782  char *name;
783  Range *range;
784  Datum datum;
785 
786  ensure_init();
787 
788  name = strfromtext(PG_GETARG_TEXT_P(0));
789  range = GetRange(name, false);
790 
791  datum = (datum_from_range(range->min, range->max));
792 
793  PG_RETURN_DATUM(datum);
794 }
795 
796 PG_FUNCTION_INFO_V1(veil_init_bitmap);
797 /**
798  * <code>veil_init_bitmap(bitmap_name text, range_nametext) returns bool</code>
799  * Create or re-initialise a Bitmap, for dealing with a named range of
800  * values.
801  * An error will be raised if the variable already exists and is not a
802  * Bitmap.
803  *
804  * @param fcinfo <code>bitmap_name text</code> The name of the bitmap to
805  * create or reset
806  * <br><code>range_name text</code> The name of a Range variable that
807  * defines the range of the new bitmap.
808  * @return <code>bool</code> true
809  */
810 Datum
811 veil_init_bitmap(PG_FUNCTION_ARGS)
812 {
813  char *bitmap_name;
814  char *range_name;
815  Bitmap *bitmap;
816  VarEntry *bitmap_var;
817  Range *range;
818 
819  ensure_init();
820 
821  bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
822  bitmap_var = vl_lookup_variable(bitmap_name);
823  bitmap = GetBitmapFromVar(bitmap_var, true, false);
824  range_name = strfromtext(PG_GETARG_TEXT_P(1));
825  range = GetRange(range_name, false);
826 
827  vl_NewBitmap(&bitmap, bitmap_var->shared, range->min, range->max);
828 
829  bitmap_var->obj = (Object *) bitmap;
830 
831  PG_RETURN_BOOL(true);
832 }
833 
834 PG_FUNCTION_INFO_V1(veil_clear_bitmap);
835 /**
836  * <code>veil_clear_bitmap(name text) returns bool</code>
837  * Clear all bits in the specified Bitmap.
838  * An error will be raised if the variable is not a Bitmap or BitmapRef.
839  *
840  * @param fcinfo <code>name text</code> The name of the bitmap to
841  * be cleared.
842  * @return <code>bool</code> true
843  */
844 Datum
845 veil_clear_bitmap(PG_FUNCTION_ARGS)
846 {
847  char *bitmap_name;
848  VarEntry *bitmap_var;
849  Bitmap *bitmap;
850 
851  ensure_init();
852 
853  bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
854  bitmap_var = vl_lookup_variable(bitmap_name);
855  bitmap = GetBitmapFromVar(bitmap_var, false, true);
856 
857  vl_ClearBitmap(bitmap);
858 
859  PG_RETURN_BOOL(true);
860 }
861 
862 PG_FUNCTION_INFO_V1(veil_bitmap_setbit);
863 /**
864  * <code>veil_bitmap_setbit(name text, bit_number int4) returns bool</code>
865  * Set the specified bit in the specified Bitmap.
866  *
867  * An error will be raised if the variable is not a Bitmap or BitmapRef.
868  *
869  * @param fcinfo <code>name text</code> The name of the bitmap variable.
870  * <br><code>bit_number int4</code> The bit to be set.
871  * @return <code>bool</code> true
872  */
873 Datum
874 veil_bitmap_setbit(PG_FUNCTION_ARGS)
875 {
876  char *name;
877  Bitmap *bitmap;
878  int32 bit;
879 
880  ensure_init();
881 
882  name = strfromtext(PG_GETARG_TEXT_P(0));
883  bit = PG_GETARG_INT32(1);
884  bitmap = GetBitmap(name, false, true);
885  vl_BitmapSetbit(bitmap, bit);
886 
887  PG_RETURN_BOOL(true);
888 }
889 
890 PG_FUNCTION_INFO_V1(veil_bitmap_clearbit);
891 /**
892  * <code>veil_bitmap_clearbit(name int4, bit_number text) returns bool</code>
893  * Clear the specified bit in the specified Bitmap.
894  *
895  * An error will be raised if the variable is not a Bitmap or BitmapRef.
896  *
897  * @param fcinfo <code>name text</code> The name of the bitmap variable.
898  * <br><code>bit_number int4</code> The bit to be cleared.
899  * @return <code>bool</code> true
900  */
901 Datum
902 veil_bitmap_clearbit(PG_FUNCTION_ARGS)
903 {
904  char *name;
905  Bitmap *bitmap;
906  int32 bit;
907 
908  ensure_init();
909 
910  name = strfromtext(PG_GETARG_TEXT_P(0));
911  bit = PG_GETARG_INT32(1);
912  bitmap = GetBitmap(name, false, true);
913  vl_BitmapClearbit(bitmap, bit);
914 
915  PG_RETURN_BOOL(true);
916 }
917 
918 PG_FUNCTION_INFO_V1(veil_bitmap_testbit);
919 /**
920  * <code>veil_bitmap_testbit(name text, bit_number int4) returns bool</code>
921  * Test the specified bit in the specified Bitmap, returning true if it
922  * is set.
923  *
924  * An error will be raised if the variable is not a Bitmap or BitmapRef.
925  *
926  * @param fcinfo <code>name text</code> The name of the bitmap variable.
927  * <br><code>bit_number int4</code> The bit to be tested.
928  * @return <code>bool</code> true if the bit was set
929  */
930 Datum
931 veil_bitmap_testbit(PG_FUNCTION_ARGS)
932 {
933  char *name;
934  Bitmap *bitmap;
935  int32 bit;
936  bool result;
937 
938  ensure_init();
939 
940  bit = PG_GETARG_INT32(1);
941  name = strfromtext(PG_GETARG_TEXT_P(0));
942  bitmap = GetBitmap(name, false, true);
943 
944  result = vl_BitmapTestbit(bitmap, bit);
945  PG_RETURN_BOOL(result);
946 }
947 
948 
949 PG_FUNCTION_INFO_V1(veil_bitmap_union);
950 /**
951  * <code>veil_bitmap_union(result_name text, name2 text) returns bool</code>
952  * Union the bitmap specified in parameter 1 with that in parameter 2,
953  * with the result in parameter 1.
954  *
955  * An error will be raised if the variables are not of type Bitmap or
956  * BitmapRef.
957  *
958  * @param fcinfo <code>result_name text</code> The target bitmap
959  * <br><code>name2 text</code> The bitmap with which to union the target
960  * @return <code>bool</code> true
961  */
962 Datum
963 veil_bitmap_union(PG_FUNCTION_ARGS)
964 {
965  char *bitmap1_name;
966  char *bitmap2_name;
967  Bitmap *target;
968  Bitmap *source;
969 
970  ensure_init();
971 
972  bitmap1_name = strfromtext(PG_GETARG_TEXT_P(0));
973  bitmap2_name = strfromtext(PG_GETARG_TEXT_P(1));
974  target = GetBitmap(bitmap1_name, false, true);
975  source = GetBitmap(bitmap2_name, false, true);
976 
977  if (target && source) {
978  vl_BitmapUnion(target, source);
979  }
980 
981  PG_RETURN_BOOL(true);
982 }
983 
984 
985 PG_FUNCTION_INFO_V1(veil_bitmap_intersect);
986 /**
987  * <code>veil_bitmap_intersect(result_name text, name2 text) returns bool</code>
988  * Intersect the bitmap specified in parameter 1 with that in parameter 2,
989  * with the result in parameter 1.
990  *
991  * An error will be raised if the variables are not of type Bitmap or
992  * BitmapRef.
993  *
994  * @param fcinfo <code>result_name text</code> The target bitmap
995  * <br><code>name2 text</code> The bitmap with which to intersect the target
996  * @return <code>bool</code> true
997  */
998 Datum
999 veil_bitmap_intersect(PG_FUNCTION_ARGS)
1000 {
1001  char *bitmap1_name;
1002  char *bitmap2_name;
1003  Bitmap *target;
1004  Bitmap *source;
1005 
1006  ensure_init();
1007 
1008  bitmap1_name = strfromtext(PG_GETARG_TEXT_P(0));
1009  bitmap2_name = strfromtext(PG_GETARG_TEXT_P(1));
1010  target = GetBitmap(bitmap1_name, false, true);
1011  source = GetBitmap(bitmap2_name, false, true);
1012 
1013  vl_BitmapIntersect(target, source);
1014  PG_RETURN_BOOL(true);
1015 }
1016 
1017 
1018 PG_FUNCTION_INFO_V1(veil_bitmap_bits);
1019 /**
1020  * <code>veil_bitmap_bits(name text)</code> returns setof int4
1021  * Return the set of all bits set in the specified Bitmap or BitmapRef.
1022  *
1023  * @param fcinfo <code>name text</code> The name of the bitmap.
1024  * @return <code>setof int4</code>The set of bits that are set in the
1025  * bitmap.
1026  */
1027 Datum
1028 veil_bitmap_bits(PG_FUNCTION_ARGS)
1029 {
1030  struct bitmap_bits_state {
1031  Bitmap *bitmap;
1032  int32 bit;
1033  } *state;
1034  FuncCallContext *funcctx;
1035  MemoryContext oldcontext;
1036  char *name;
1037  bool found;
1038  Datum datum;
1039 
1040  if (SRF_IS_FIRSTCALL())
1041  {
1042  /* Only do this on first call for this result set */
1043  ensure_init();
1044 
1045  funcctx = SRF_FIRSTCALL_INIT();
1046  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1047  state = palloc(sizeof(struct bitmap_bits_state));
1048  MemoryContextSwitchTo(oldcontext);
1049 
1050  name = strfromtext(PG_GETARG_TEXT_P(0));
1051  state->bitmap = GetBitmap(name, false, true);
1052 
1053  if (!state->bitmap) {
1054  ereport(ERROR,
1055  (errcode(ERRCODE_INTERNAL_ERROR),
1056  errmsg("Bitmap %s is not defined",
1057  name),
1058  errhint("Perhaps the name is mis-spelled, or its "
1059  "definition is missing from veil_init().")));
1060  }
1061 
1062  state->bit = state->bitmap->bitzero;
1063  funcctx->user_fctx = state;
1064  }
1065 
1066  funcctx = SRF_PERCALL_SETUP();
1067  state = funcctx->user_fctx;
1068 
1069  state->bit = vl_BitmapNextBit(state->bitmap, state->bit, &found);
1070 
1071  if (found) {
1072  datum = Int32GetDatum(state->bit);
1073  state->bit++;
1074  SRF_RETURN_NEXT(funcctx, datum);
1075  }
1076  else {
1077  SRF_RETURN_DONE(funcctx);
1078  }
1079 }
1080 
1081 PG_FUNCTION_INFO_V1(veil_bitmap_range);
1082 /**
1083  * <code>veil_bitmap_range(name text) returns veil_range_t</code>
1084  * Return composite type giving the range of the specified Bitmap or
1085  * BitmapRef.
1086  *
1087  * @param fcinfo <code>name text</code> The name of the bitmap.
1088  * @return <code>veil_range_t</code> Composite type containing the min
1089  * and max values of the bitmap's range
1090  */
1091 Datum
1092 veil_bitmap_range(PG_FUNCTION_ARGS)
1093 {
1094  char *name;
1095  Bitmap *bitmap;
1096 
1097  ensure_init();
1098 
1099  name = strfromtext(PG_GETARG_TEXT_P(0));
1100  bitmap = GetBitmap(name, false, true);
1101 
1102  if (!bitmap) {
1103  ereport(ERROR,
1104  (errcode(ERRCODE_INTERNAL_ERROR),
1105  errmsg("Bitmap %s is not defined", name),
1106  errhint("Perhaps the name is mis-spelled, or its "
1107  "definition is missing from veil_init().")));
1108  }
1109 
1110  PG_RETURN_DATUM(datum_from_range(bitmap->bitzero, bitmap->bitmax));
1111 }
1112 
1113 
1114 PG_FUNCTION_INFO_V1(veil_init_bitmap_array);
1115 /**
1116  * <code>veil_init_bitmap_array(text, text, text) returns bool</code>
1117  * Create or reset a BitmapArray.
1118  * An error will be raised if any parameter is not of the correct type.
1119  *
1120  * @param fcinfo <code>bmarray text</code> The name of the bitmap array.
1121  * <br><code>array_range text</code> Name of the Range variable that
1122  * provides the range of the array part of the bitmap array.
1123  * <br><code>bitmap_range text</code> Name of the Range variable that
1124  * provides the range of each bitmap in the array.
1125  * @return <code>bool</code> True
1126  */
1127 Datum
1128 veil_init_bitmap_array(PG_FUNCTION_ARGS)
1129 {
1130  char *bmarray_name;
1131  char *arrayrange_name;
1132  char *maprange_name;
1133  VarEntry *bmarray_var;
1134  BitmapArray *bmarray;
1135  Range *arrayrange;
1136  Range *maprange;
1137 
1138  ensure_init();
1139 
1140  bmarray_name = strfromtext(PG_GETARG_TEXT_P(0));
1141  bmarray_var = vl_lookup_variable(bmarray_name);
1142  bmarray = GetBitmapArrayFromVar(bmarray_var, true);
1143 
1144  arrayrange_name = strfromtext(PG_GETARG_TEXT_P(1));
1145  arrayrange = GetRange(arrayrange_name, false);
1146  maprange_name = strfromtext(PG_GETARG_TEXT_P(2));
1147  maprange = GetRange(maprange_name, false);
1148 
1149  vl_NewBitmapArray(&bmarray, bmarray_var->shared,
1150  arrayrange->min, arrayrange->max,
1151  maprange->min, maprange->max);
1152 
1153  bmarray_var->obj = (Object *) bmarray;
1154 
1155  PG_RETURN_BOOL(true);
1156 }
1157 
1158 PG_FUNCTION_INFO_V1(veil_clear_bitmap_array);
1159 /**
1160  * <code>veil_clear_bitmap_array(bmarray text) returns bool</code>
1161  * Clear the bits in an existing BitmapArray.
1162  * An error will be raised if the parameter is not of the correct type.
1163  *
1164  * @param fcinfo <code>bmarray text</code> The name of the BitmapArray.
1165  * @return <code>bool</code> True
1166  */
1167 Datum
1168 veil_clear_bitmap_array(PG_FUNCTION_ARGS)
1169 {
1170  char *bmarray_name;
1171  VarEntry *bmarray_var;
1172  BitmapArray *bmarray;
1173 
1174  ensure_init();
1175 
1176  bmarray_name = strfromtext(PG_GETARG_TEXT_P(0));
1177  bmarray_var = vl_lookup_variable(bmarray_name);
1178  bmarray = GetBitmapArrayFromVar(bmarray_var, false);
1179 
1180  vl_ClearBitmapArray(bmarray);
1181 
1182  PG_RETURN_BOOL(true);
1183 }
1184 
1185 PG_FUNCTION_INFO_V1(veil_bitmap_from_array);
1186 /**
1187  * <code>veil_bitmap_from_array(bmref text, bmarray text, index int4) returns text</code>
1188  * Place a reference to the specified Bitmap from a BitmapArray into
1189  * the specified BitmapRef
1190  * An error will be raised if any parameter is not of the correct type.
1191  *
1192  * @param fcinfo <code>bmref text</code> The name of the BitmapRef into which
1193  * a reference to the relevant Bitmap will be placed.
1194  * <br><code>bmarray text</code> Name of the BitmapArray containing the Bitmap
1195  * in which we are interested.
1196  * <br><code>index int4</code> Index into the array of the bitmap in question.
1197  * @return <code>text</code> The name of the BitmapRef
1198  */
1199 Datum
1200 veil_bitmap_from_array(PG_FUNCTION_ARGS)
1201 {
1202  text *bmref_text;
1203  char *bmref_name;
1204  BitmapRef *bmref;
1205  char *bmarray_name;
1206  BitmapArray *bmarray;
1207  int32 arrayelem;
1208  Bitmap *bitmap;
1209 
1210  bmref_text = PG_GETARG_TEXT_P(0);
1211  bmref_name = strfromtext(bmref_text);
1212  bmref = GetBitmapRef(bmref_name);
1213 
1214  bmarray_name = strfromtext(PG_GETARG_TEXT_P(1));
1215  bmarray = GetBitmapArray(bmarray_name, false);
1216 
1217  arrayelem = PG_GETARG_INT32(2);
1218  bitmap = vl_BitmapFromArray(bmarray, arrayelem);
1219  if (!bitmap) {
1220  ereport(ERROR,
1221  (errcode(ERRCODE_INTERNAL_ERROR),
1222  errmsg("Range error for BitmapArray %s, %d not in %d - %d",
1223  bmarray_name, arrayelem,
1224  bmarray->arrayzero, bmarray->arraymax)));
1225  }
1226 
1227  bmref->bitmap = bitmap;
1228  bmref->xid = GetCurrentTransactionId();
1229  PG_RETURN_TEXT_P(bmref_text);
1230 }
1231 
1232 PG_FUNCTION_INFO_V1(veil_bitmap_array_testbit);
1233 /**
1234  * <code>veil_bitmap_array_testbit(bmarray text, arr_idx int4, bitno int4) returns bool</code>
1235  * Test a specified bit within a BitmapArray
1236  *
1237  * An error will be raised if the first parameter is not a BitmapArray.
1238  *
1239  * @param fcinfo <code>bmarray text</code> The name of the BitmapArray
1240  * <br><code>arr_idx int4</code> Index of the Bitmap within the array.
1241  * <br><code>bitno int4</code> Bit id of the bit within the Bitmap.
1242  * @return <code>bool</code> True if the bit was set, false otherwise.
1243  */
1244 Datum
1245 veil_bitmap_array_testbit(PG_FUNCTION_ARGS)
1246 {
1247  char *name;
1248  BitmapArray *bmarray;
1249  Bitmap *bitmap;
1250  int32 arrayelem;
1251  int32 bit;
1252 
1253  ensure_init();
1254 
1255  arrayelem = PG_GETARG_INT32(1);
1256  bit = PG_GETARG_INT32(2);
1257 
1258  name = strfromtext(PG_GETARG_TEXT_P(0));
1259  bmarray = GetBitmapArray(name, false);
1260 
1261  bitmap = vl_BitmapFromArray(bmarray, arrayelem);
1262  if (bitmap) {
1263  PG_RETURN_BOOL(vl_BitmapTestbit(bitmap, bit));
1264  }
1265  else {
1266  PG_RETURN_BOOL(false);
1267  }
1268 }
1269 
1270 
1271 PG_FUNCTION_INFO_V1(veil_bitmap_array_setbit);
1272 /**
1273  * <code>veil_bitmap_array_setbit(bmarray text, arr_idx int4, bitno int4) returns bool</code>
1274  * Set a specified bit within a BitmapArray
1275  *
1276  * An error will be raised if the first parameter is not a BitmapArray.
1277  *
1278  * @param fcinfo <code>bmarray text</code> The name of the BitmapArray
1279  * <br><code>arr_idx int4</code> Index of the Bitmap within the array.
1280  * <br><code>ibitno nt4</code> Bit id of the bit within the Bitmap.
1281  * @return <code>bool</code> True
1282  */
1283 Datum
1284 veil_bitmap_array_setbit(PG_FUNCTION_ARGS)
1285 {
1286  char *name;
1287  BitmapArray *bmarray;
1288  Bitmap *bitmap;
1289  int32 arrayelem;
1290  int32 bit;
1291 
1292  ensure_init();
1293 
1294  arrayelem = PG_GETARG_INT32(1);
1295  bit = PG_GETARG_INT32(2);
1296  name = strfromtext(PG_GETARG_TEXT_P(0));
1297  bmarray = GetBitmapArray(name, false);
1298 
1299  bitmap = vl_BitmapFromArray(bmarray, arrayelem);
1300  if (bitmap) {
1301  vl_BitmapSetbit(bitmap, bit);
1302  PG_RETURN_BOOL(true);
1303  }
1304  else {
1305  ereport(ERROR,
1306  (errcode(ERRCODE_INTERNAL_ERROR),
1307  errmsg("Bitmap Array range error (%d not in %d..%d)",
1308  arrayelem, bmarray->arrayzero, bmarray->arraymax),
1309  errdetail("Attempt to reference BitmapArray element "
1310  "outside of the BitmapArray's defined range")));
1311  }
1312  PG_RETURN_BOOL(true);
1313 }
1314 
1315 
1316 PG_FUNCTION_INFO_V1(veil_bitmap_array_clearbit);
1317 /**
1318  * <code>veil_bitmap_array_clearbit(bmarray text, arr_idx int4, bitno int4) returns bool</code>
1319  * Clear a specified bit within a BitmapArray
1320  *
1321  * An error will be raised if the first parameter is not a BitmapArray.
1322  *
1323  * @param fcinfo <code>bmarray text</code> The name of the BitmapArray
1324  * <br><code>arr_idx int4</code> Index of the Bitmap within the array.
1325  * <br><code>bitno int4</code> Bit id of the bit within the Bitmap.
1326  * @return <code>bool</code> True
1327  */
1328 Datum
1330 {
1331  char *name;
1332  BitmapArray *bmarray;
1333  Bitmap *bitmap;
1334  int32 arrayelem;
1335  int32 bit;
1336 
1337  ensure_init();
1338 
1339  arrayelem = PG_GETARG_INT32(1);
1340  bit = PG_GETARG_INT32(2);
1341  name = strfromtext(PG_GETARG_TEXT_P(0));
1342  bmarray = GetBitmapArray(name, false);
1343 
1344  bitmap = vl_BitmapFromArray(bmarray, arrayelem);
1345  if (bitmap) {
1346  vl_BitmapClearbit(bitmap, bit);
1347  PG_RETURN_BOOL(true);
1348  }
1349  else {
1350  ereport(ERROR,
1351  (errcode(ERRCODE_INTERNAL_ERROR),
1352  errmsg("Bitmap Array range error (%d not in %d..%d)",
1353  arrayelem, bmarray->arrayzero, bmarray->arraymax),
1354  errdetail("Attempt to reference BitmapArray element "
1355  "outside of the BitmapArray's defined range")));
1356  }
1357  PG_RETURN_BOOL(true);
1358 }
1359 
1360 
1361 PG_FUNCTION_INFO_V1(veil_union_from_bitmap_array);
1362 /**
1363  * <code>veil_union_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool</code>
1364  * Union a Bitmap with the specified Bitmap from a BitmapArray with the
1365  * result placed into the first parameter.
1366  *
1367  * An error will be raised if the parameters are not of the correct types.
1368  *
1369  * @param fcinfo <code>bitmap text</code> The name of the Bitmap into which the
1370  * resulting union will be placed.
1371  * <br><code>bmarray text</code> Name of the BitmapArray
1372  * <br><code>arr_idx int4</code> Index of the required bitmap in the array
1373  * @return <code>bool</code> True
1374  */
1375 Datum
1377 {
1378  char *bitmap_name;
1379  char *bmarray_name;
1380  Bitmap *target;
1381  BitmapArray *bmarray;
1382  Bitmap *bitmap;
1383  int32 arrayelem;
1384 
1385  ensure_init();
1386 
1387  arrayelem = PG_GETARG_INT32(2);
1388 
1389  bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
1390  bmarray_name = strfromtext(PG_GETARG_TEXT_P(1));
1391  target = GetBitmap(bitmap_name, false, true);
1392  bmarray = GetBitmapArray(bmarray_name, false);
1393 
1394  bitmap = vl_BitmapFromArray(bmarray, arrayelem);
1395  if (bitmap) {
1396  vl_BitmapUnion(target, bitmap);
1397  }
1398  PG_RETURN_BOOL(true);
1399 }
1400 
1401 
1402 PG_FUNCTION_INFO_V1(veil_intersect_from_bitmap_array);
1403 /**
1404  * <code>veil_intersect_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool</code>
1405  * Intersect a Bitmap with the specified Bitmap from a BitmapArray with the
1406  * result placed into the first parameter.
1407  *
1408  * An error will be raised if the parameters are not of the correct types.
1409  *
1410  * @param fcinfo <code>bitmap text</code> The name of the Bitmap into which the
1411  * resulting intersection will be placed.
1412  * <br><code>bmarray text</code> Name of the BitmapArray
1413  * <br><code>arr_idx int4</code> Index of the required bitmap in the array
1414  * @return <code>bool</code> True
1415  */
1416 Datum
1418 {
1419  char *bitmap_name;
1420  char *bmarray_name;
1421  Bitmap *target;
1422  BitmapArray *bmarray;
1423  Bitmap *bitmap;
1424  int32 arrayelem;
1425 
1426  ensure_init();
1427 
1428  arrayelem = PG_GETARG_INT32(2);
1429 
1430  bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
1431  bmarray_name = strfromtext(PG_GETARG_TEXT_P(1));
1432  target = GetBitmap(bitmap_name, false, true);
1433  bmarray = GetBitmapArray(bmarray_name, false);
1434 
1435  bitmap = vl_BitmapFromArray(bmarray, arrayelem);
1436  if (bitmap) {
1437  vl_BitmapIntersect(target, bitmap);
1438  }
1439  PG_RETURN_BOOL(true);
1440 }
1441 
1442 
1443 PG_FUNCTION_INFO_V1(veil_bitmap_array_bits);
1444 /**
1445  * <code>veil_bitmap_array_bits(bmarray text, arr_idx int4)</code> returns setof int4
1446  * Return the set of all bits set in the specified Bitmap from the
1447  * BitmapArray.
1448  *
1449  * @param fcinfo <code>bmarray text</code> The name of the bitmap array.
1450  * <br><code>arr_idx int4</code> Index of the required bitmap in the array
1451  * @return <code>setof int4</code>The set of bits that are set in the
1452  * bitmap.
1453  */
1454 Datum
1455 veil_bitmap_array_bits(PG_FUNCTION_ARGS)
1456 {
1457  struct bitmap_array_bits_state {
1458  Bitmap *bitmap;
1459  int32 bit;
1460  } *state;
1461  FuncCallContext *funcctx;
1462  MemoryContext oldcontext;
1463  char *name;
1464  bool found;
1465  BitmapArray *bmarray;
1466  int arrayelem;
1467  Datum datum;
1468 
1469  if (SRF_IS_FIRSTCALL())
1470  {
1471  /* Only do this on first call for this result set */
1472  ensure_init();
1473 
1474  funcctx = SRF_FIRSTCALL_INIT();
1475  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
1476  state = palloc(sizeof(struct bitmap_array_bits_state));
1477  MemoryContextSwitchTo(oldcontext);
1478 
1479  name = strfromtext(PG_GETARG_TEXT_P(0));
1480  arrayelem = PG_GETARG_INT32(1);
1481  bmarray = GetBitmapArray(name, false);
1482 
1483  if (!bmarray) {
1484  ereport(ERROR,
1485  (errcode(ERRCODE_INTERNAL_ERROR),
1486  errmsg("BitmapArray %s is not defined",
1487  name),
1488  errhint("Perhaps the name is mis-spelled, or its "
1489  "definition is missing from "
1490  "veil_init().")));
1491  }
1492 
1493  state->bitmap = vl_BitmapFromArray(bmarray, arrayelem);
1494  if (!state->bitmap) {
1495  ereport(ERROR,
1496  (errcode(ERRCODE_INTERNAL_ERROR),
1497  errmsg("Bitmap Array range error (%d not in %d..%d)",
1498  arrayelem, bmarray->arrayzero, bmarray->arraymax),
1499  errdetail("Attempt to reference BitmapArray element "
1500  "outside of the BitmapArray's defined range")));
1501  }
1502 
1503  state->bit = state->bitmap->bitzero;
1504  funcctx->user_fctx = state;
1505  }
1506 
1507  funcctx = SRF_PERCALL_SETUP();
1508  state = funcctx->user_fctx;
1509 
1510  state->bit = vl_BitmapNextBit(state->bitmap, state->bit, &found);
1511 
1512  if (found) {
1513  datum = Int32GetDatum(state->bit);
1514  state->bit++;
1515  SRF_RETURN_NEXT(funcctx, datum);
1516  }
1517  else {
1518  SRF_RETURN_DONE(funcctx);
1519  }
1520 }
1521 
1522 PG_FUNCTION_INFO_V1(veil_bitmap_array_arange);
1523 /**
1524  * <code>veil_bitmap_array_arange(bmarray text) returns veil_range_t</code>
1525  * Return composite type giving the range of the array part of the
1526  * specified BitmapArray
1527  *
1528  * @param fcinfo <code>bmarray text</code> The name of the bitmap array.
1529  * @return <code>veil_range_t</code> Composite type containing the min
1530  * and max indices of the array
1531  */
1532 Datum
1533 veil_bitmap_array_arange(PG_FUNCTION_ARGS)
1534 {
1535  char *name;
1536  BitmapArray *bmarray;
1537 
1538  ensure_init();
1539 
1540  name = strfromtext(PG_GETARG_TEXT_P(0));
1541  bmarray = GetBitmapArray(name, false);
1542 
1543  if (!bmarray) {
1544  ereport(ERROR,
1545  (errcode(ERRCODE_INTERNAL_ERROR),
1546  errmsg("BitmapArray %s is not defined",
1547  name),
1548  errhint("Perhaps the name is mis-spelled, or its "
1549  "definition is missing from veil_init().")));
1550  }
1551 
1552  PG_RETURN_DATUM(datum_from_range(bmarray->arrayzero, bmarray->arraymax));
1553 }
1554 
1555 
1556 PG_FUNCTION_INFO_V1(veil_bitmap_array_brange);
1557 /**
1558  * <code>veil_bitmap_array_brange(bmarray text) returns veil_range_t</code>
1559  * Return composite type giving the range of every Bitmap within
1560  * the BitmapArray.
1561  *
1562  * @param fcinfo <code>bmarray text</code> The name of the bitmap array.
1563  * @return <code>veil_range_t</code> Composite type containing the min
1564  * and max values of the bitmap array's range
1565  */
1566 Datum
1567 veil_bitmap_array_brange(PG_FUNCTION_ARGS)
1568 {
1569  char *name;
1570  BitmapArray *bmarray;
1571 
1572  ensure_init();
1573 
1574  name = strfromtext(PG_GETARG_TEXT_P(0));
1575  bmarray = GetBitmapArray(name, false);
1576 
1577  if (!bmarray) {
1578  ereport(ERROR,
1579  (errcode(ERRCODE_INTERNAL_ERROR),
1580  errmsg("BitmapArray %s is not defined",
1581  name),
1582  errhint("Perhaps the name is mis-spelled, or its "
1583  "definition is missing from veil_init().")));
1584  }
1585 
1586  PG_RETURN_DATUM(datum_from_range(bmarray->bitzero, bmarray->bitmax));
1587 }
1588 
1589 
1590 
1591 PG_FUNCTION_INFO_V1(veil_init_bitmap_hash);
1592 /**
1593  * <code>veil_init_bitmap_hash(bmhash text, range text) returns bool</code>
1594  * Create or reset a BitmapHash.
1595  * An error will be raised if any parameter is not of the correct type.
1596  *
1597  * @param fcinfo <code>bmhash text</code> The name of the bitmap hash.
1598  * <br><code>range text</code> Name of the Range variable that provides the
1599  * range of each bitmap in the hash.
1600  * @return <code>bool</code> True
1601  */
1602 Datum
1603 veil_init_bitmap_hash(PG_FUNCTION_ARGS)
1604 {
1605  char *bmhash_name;
1606  char *range_name;
1607  VarEntry *bmhash_var;
1608  BitmapHash *bmhash;
1609  Range *range;
1610 
1611  ensure_init();
1612 
1613  bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
1614  bmhash_var = vl_lookup_variable(bmhash_name);
1615  bmhash = GetBitmapHashFromVar(bmhash_var, true);
1616 
1617  range_name = strfromtext(PG_GETARG_TEXT_P(1));
1618  range = GetRange(range_name, false);
1619 
1620  if (bmhash_var->shared) {
1621  ereport(ERROR,
1622  (errcode(ERRCODE_INTERNAL_ERROR),
1623  errmsg("illegal attempt to define shared BitmapHash %s",
1624  bmhash_name),
1625  errhint("BitmapHashes may only be defined as session, "
1626  "not shared, variables.")));
1627  }
1628  vl_NewBitmapHash(&bmhash, bmhash_name,
1629  range->min, range->max);
1630 
1631  bmhash_var->obj = (Object *) bmhash;
1632 
1633  PG_RETURN_BOOL(true);
1634 }
1635 
1636 
1637 PG_FUNCTION_INFO_V1(veil_clear_bitmap_hash);
1638 /**
1639  * <code>veil_clear_bitmap_hash(bmhash text) returns bool</code>
1640  * Clear the bits in an existing BitmapHash.
1641  * An error will be raised if the parameter is not of the correct type.
1642  *
1643  * @param fcinfo <code>bmhash text</code> The name of the BitmapHash.
1644  * @return <code>bool</code> True
1645  */
1646 Datum
1647 veil_clear_bitmap_hash(PG_FUNCTION_ARGS)
1648 {
1649  char *bmhash_name;
1650  VarEntry *bmhash_var;
1651  BitmapHash *bmhash;
1652 
1653  ensure_init();
1654 
1655  bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
1656  bmhash_var = vl_lookup_variable(bmhash_name);
1657  bmhash = GetBitmapHashFromVar(bmhash_var, true);
1658 
1659  vl_NewBitmapHash(&bmhash, bmhash_name,
1660  bmhash->bitzero, bmhash->bitmax);
1661 
1662  bmhash_var->obj = (Object *) bmhash;
1663 
1664  PG_RETURN_BOOL(true);
1665 }
1666 
1667 
1668 PG_FUNCTION_INFO_V1(veil_bitmap_hash_key_exists);
1669 /**
1670  * <code>veil_bitmap_hashkey_exists(bmhash text, key text) returns bool</code>
1671  * Return true if the key exists in the bitmap hash.
1672  *
1673  * @param fcinfo <code>bmhash text</code> Name of the BitmapHashin which we are
1674  * interested.
1675  * <br><code>key text</code> Key, into the hash, of the bitmap in question.
1676  * @return <code>boolean</code> Whether the key is present in the BitmapHash
1677  */
1678 Datum
1680 {
1681  char *bmhash_name;
1682  BitmapHash *bmhash;
1683  char *hashelem;
1684  bool found;
1685 
1686  bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
1687  bmhash = GetBitmapHash(bmhash_name, false);
1688 
1689  hashelem = strfromtext(PG_GETARG_TEXT_P(1));
1690 
1691  found = vl_BitmapHashHasKey(bmhash, hashelem);
1692 
1693  PG_RETURN_BOOL(found);
1694 }
1695 
1696 PG_FUNCTION_INFO_V1(veil_bitmap_from_hash);
1697 /**
1698  * <code>veil_bitmap_from_hash(bmref text, bmhash text, key text) returns text</code>
1699  * Place a reference to the specified Bitmap from a BitmapHash into
1700  * the specified BitmapRef
1701  * An error will be raised if any parameter is not of the correct type.
1702  *
1703  * @param fcinfo <code>bmref text</code> The name of the BitmapRef into which
1704  * a reference to the relevant Bitmap will be placed.
1705  * <br><code>bmhash text</code> Name of the BitmapHash containing the Bitmap
1706  * in which we are interested.
1707  * <br><code>key text</code> Key, into the hash, of the bitmap in question.
1708  * @return <code>text</code> The name of the BitmapRef
1709  */
1710 Datum
1711 veil_bitmap_from_hash(PG_FUNCTION_ARGS)
1712 {
1713  text *bmref_text;
1714  char *bmref_name;
1715  BitmapRef *bmref;
1716  char *bmhash_name;
1717  BitmapHash *bmhash;
1718  char *hashelem;
1719  Bitmap *bitmap;
1720 
1721  bmref_text = PG_GETARG_TEXT_P(0);
1722  bmref_name = strfromtext(bmref_text);
1723  bmref = GetBitmapRef(bmref_name);
1724 
1725  bmhash_name = strfromtext(PG_GETARG_TEXT_P(1));
1726  bmhash = GetBitmapHash(bmhash_name, false);
1727 
1728  hashelem = strfromtext(PG_GETARG_TEXT_P(2));
1729  bitmap = vl_AddBitmapToHash(bmhash, hashelem);
1730 
1731  bmref->bitmap = bitmap;
1732  bmref->xid = GetCurrentTransactionId();
1733  PG_RETURN_TEXT_P(bmref_text);
1734 }
1735 
1736 
1737 PG_FUNCTION_INFO_V1(veil_bitmap_hash_testbit);
1738 /**
1739  * <code>veil_bitmap_hash_testbit(bmhash text, key text, bitno int4) returns bool</code>
1740  * Test a specified bit within a BitmapHash
1741  *
1742  * An error will be raised if the first parameter is not a BitmapHash.
1743  *
1744  * @param fcinfo <code>bmhash text</code> The name of the BitmapHash
1745  * <br><code>key text</code> Key of the Bitmap within the hash.
1746  * <br><code>bitno int4</code> Bit id of the bit within the Bitmap.
1747  * @return <code>bool</code> True if the bit was set, false otherwise.
1748  */
1749 Datum
1750 veil_bitmap_hash_testbit(PG_FUNCTION_ARGS)
1751 {
1752  char *name;
1753  BitmapHash *bmhash;
1754  char *hashelem;
1755  Bitmap *bitmap;
1756  int32 bit;
1757 
1758  ensure_init();
1759 
1760  hashelem = strfromtext(PG_GETARG_TEXT_P(1));
1761  bit = PG_GETARG_INT32(2);
1762 
1763  name = strfromtext(PG_GETARG_TEXT_P(0));
1764  bmhash = GetBitmapHash(name, false);
1765 
1766  bitmap = vl_BitmapFromHash(bmhash, hashelem);
1767  if (bitmap) {
1768  PG_RETURN_BOOL(vl_BitmapTestbit(bitmap, bit));
1769  }
1770  else {
1771  PG_RETURN_BOOL(false);
1772  }
1773 }
1774 
1775 
1776 PG_FUNCTION_INFO_V1(veil_bitmap_hash_setbit);
1777 /**
1778  * <code>veil_bitmap_hash_setbit(bmhash text, key text, bitno int4) returns bool</code>
1779  * Set a specified bit within a BitmapHash
1780  *
1781  * An error will be raised if the first parameter is not a BitmapHash.
1782  *
1783  * @param fcinfo <code>bmhash text</code> The name of the BitmapHash
1784  * <br><code>key text</code> Key of the Bitmap within the hash.
1785  * <br><code>bitno int4</code> Bit id of the bit within the Bitmap.
1786  * @return <code>bool</code> True
1787  */
1788 Datum
1789 veil_bitmap_hash_setbit(PG_FUNCTION_ARGS)
1790 {
1791  char *name;
1792  BitmapHash *bmhash;
1793  Bitmap *bitmap;
1794  char *hashelem;
1795  int32 bit;
1796 
1797  ensure_init();
1798 
1799  hashelem = strfromtext(PG_GETARG_TEXT_P(1));
1800  bit = PG_GETARG_INT32(2);
1801  name = strfromtext(PG_GETARG_TEXT_P(0));
1802  bmhash = GetBitmapHash(name, false);
1803 
1804  bitmap = vl_AddBitmapToHash(bmhash, hashelem);
1805 
1806  vl_BitmapSetbit(bitmap, bit);
1807  PG_RETURN_BOOL(true);
1808 }
1809 
1810 
1811 PG_FUNCTION_INFO_V1(veil_bitmap_hash_clearbit);
1812 /**
1813  * <code>veil_bitmap_hash_clearbit(bmhash text, key text, bitno int4) returns bool</code>
1814  * Clear a specified bit within a BitmapHash
1815  *
1816  * An error will be raised if the first parameter is not a BitmapHash.
1817  *
1818  * @param fcinfo <code>bmhash text</code> The name of the BitmapHash
1819  * <br><code>key text</code> Key of the Bitmap within the hash.
1820  * <br><code>bitno int4</code> Bit id of the bit within the Bitmap.
1821  * @return <code>bool</code> True
1822  */
1823 Datum
1824 veil_bitmap_hash_clearbit(PG_FUNCTION_ARGS)
1825 {
1826  char *name;
1827  BitmapHash *bmhash;
1828  Bitmap *bitmap;
1829  char *hashelem;
1830  int32 bit;
1831 
1832  ensure_init();
1833 
1834  hashelem = strfromtext(PG_GETARG_TEXT_P(1));
1835  bit = PG_GETARG_INT32(2);
1836  name = strfromtext(PG_GETARG_TEXT_P(0));
1837  bmhash = GetBitmapHash(name, false);
1838 
1839  bitmap = vl_AddBitmapToHash(bmhash, hashelem);
1840 
1841  vl_BitmapClearbit(bitmap, bit);
1842  PG_RETURN_BOOL(true);
1843 }
1844 
1845 
1846 PG_FUNCTION_INFO_V1(veil_union_into_bitmap_hash);
1847 /**
1848  * <code>veil_union_into_bitmap_hash(bmhash text, key text, bitmap text) returns bool</code>
1849  * Union a Bitmap with the specified Bitmap from a BitmapHash with the
1850  * result placed into the bitmap hash.
1851  *
1852  * An error will be raised if the parameters are not of the correct types.
1853  *
1854  * @param fcinfo <code>bmhash text</code> Name of the BitmapHash
1855  * <br><code>key text</code> Key of the required bitmap in the hash
1856  * <br><code>bitmap text</code> The name of the Bitmap into which the
1857  * resulting union will be placed.
1858  * @return <code>bool</code> True
1859  */
1860 Datum
1862 {
1863  char *bitmap_name;
1864  char *bmhash_name;
1865  Bitmap *target;
1866  BitmapHash *bmhash;
1867  Bitmap *bitmap;
1868  char *hashelem;
1869 
1870  ensure_init();
1871 
1872  bmhash_name = strfromtext(PG_GETARG_TEXT_P(0));
1873  hashelem = strfromtext(PG_GETARG_TEXT_P(1));
1874 
1875  bitmap_name = strfromtext(PG_GETARG_TEXT_P(2));
1876  bitmap = GetBitmap(bitmap_name, false, true);
1877  bmhash = GetBitmapHash(bmhash_name, false);
1878 
1879  target = vl_AddBitmapToHash(bmhash, hashelem);
1880  if (target && bitmap) {
1881  vl_BitmapUnion(target, bitmap);
1882  }
1883  PG_RETURN_BOOL(true);
1884 }
1885 
1886 PG_FUNCTION_INFO_V1(veil_union_from_bitmap_hash);
1887 /**
1888  * <code>veil_union_from_bitmap_hash(bmhash text, key text, bitmap text) returns bool</code>
1889  * Union a Bitmap with the specified Bitmap from a BitmapHash with the
1890  * result placed into the bitmap parameter.
1891  *
1892  * An error will be raised if the parameters are not of the correct types.
1893  *
1894  * @param fcinfo <code>bmhash text</code> The name of the Bitmap into which the
1895  * resulting union will be placed.
1896  * <br><code>key text</code> Name of the BitmapHash
1897  * <br><code>bitmap text</code> Key of the required bitmap in the hash
1898  * @return <code>bool</code> True
1899  */
1900 Datum
1902 {
1903  char *bitmap_name;
1904  char *bmhash_name;
1905  Bitmap *target;
1906  BitmapHash *bmhash;
1907  Bitmap *bitmap;
1908  char *hashelem;
1909 
1910  ensure_init();
1911 
1912  hashelem = strfromtext(PG_GETARG_TEXT_P(2));
1913 
1914  bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
1915  bmhash_name = strfromtext(PG_GETARG_TEXT_P(1));
1916  target = GetBitmap(bitmap_name, false, true);
1917  bmhash = GetBitmapHash(bmhash_name, false);
1918 
1919  bitmap = vl_BitmapFromHash(bmhash, hashelem);
1920  if (bitmap) {
1921  vl_BitmapUnion(target, bitmap);
1922  }
1923  PG_RETURN_BOOL(true);
1924 }
1925 
1926 PG_FUNCTION_INFO_V1(veil_intersect_from_bitmap_hash);
1927 /**
1928  * <code>veil_intersect_from_bitmap_hash(bitmap text, bmhash text, key text) returns bool</code>
1929  * Intersect a Bitmap with the specified Bitmap from a BitmapArray with the
1930  * result placed into the bitmap parameter.
1931  *
1932  * An error will be raised if the parameters are not of the correct types.
1933  *
1934  * @param fcinfo <code>bitmap text</code> The name of the Bitmap into which the
1935  * resulting intersection will be placed.
1936  * <br><code>bmhash text</code> Name of the BitmapHash
1937  * <br><code>key text</code> Key of the required bitmap in the hash
1938  * @return <code>bool</code> True
1939  */
1940 Datum
1942 {
1943  char *bitmap_name;
1944  char *bmhash_name;
1945  Bitmap *target;
1946  BitmapHash *bmhash;
1947  Bitmap *bitmap;
1948  char *hashelem;
1949 
1950  ensure_init();
1951 
1952  hashelem = strfromtext(PG_GETARG_TEXT_P(2));
1953 
1954  bitmap_name = strfromtext(PG_GETARG_TEXT_P(0));
1955  bmhash_name = strfromtext(PG_GETARG_TEXT_P(1));
1956  target = GetBitmap(bitmap_name, false, true);
1957  bmhash = GetBitmapHash(bmhash_name, false);
1958 
1959  bitmap = vl_BitmapFromHash(bmhash, hashelem);
1960  if (bitmap) {
1961  vl_BitmapIntersect(target, bitmap);
1962  }
1963  else {
1964  /* The bitmap from the hash does not exist, so it is logically
1965  * empty. Intersection with an empty set yields an empty set. */
1966  vl_ClearBitmap(target);
1967  }
1968  PG_RETURN_BOOL(true);
1969 }
1970 
1971 PG_FUNCTION_INFO_V1(veil_bitmap_hash_bits);
1972 /**
1973  * <code>veil_bitmap_hash_bits(bmhash text, key text)</code> returns setof int4
1974  * Return the set of all bits set in the specified Bitmap from the
1975  * BitmapHash.
1976  *
1977  * @param fcinfo <code>bmhashtext</code> The name of the bitmap hash.
1978  * <br><code>key text</code> Key of the required bitmap in the hash
1979  * @return <code>setof int4</code>The set of bits that are set in the
1980  * bitmap.
1981  */
1982 Datum
1983 veil_bitmap_hash_bits(PG_FUNCTION_ARGS)
1984 {
1985  struct bitmap_hash_bits_state {
1986  Bitmap *bitmap;
1987  int32 bit;
1988  } *state;
1989  FuncCallContext *funcctx;
1990  MemoryContext oldcontext;
1991  char *name;
1992  bool found;
1993  BitmapHash *bmhash;
1994  char *hashelem;
1995  Datum datum;
1996 
1997  if (SRF_IS_FIRSTCALL())
1998  {
1999  /* Only do this on first call for this result set */
2000  ensure_init();
2001 
2002  funcctx = SRF_FIRSTCALL_INIT();
2003  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
2004  state = palloc(sizeof(struct bitmap_hash_bits_state));
2005  MemoryContextSwitchTo(oldcontext);
2006 
2007  name = strfromtext(PG_GETARG_TEXT_P(0));
2008  hashelem = strfromtext(PG_GETARG_TEXT_P(1));
2009  bmhash = GetBitmapHash(name, false);
2010 
2011  if (!bmhash) {
2012  ereport(ERROR,
2013  (errcode(ERRCODE_INTERNAL_ERROR),
2014  errmsg("Bitmap Hash %s not defined", name)));
2015  }
2016 
2017  state->bitmap = vl_BitmapFromHash(bmhash, hashelem);
2018  if (!state->bitmap) {
2019  SRF_RETURN_DONE(funcctx);
2020  }
2021 
2022  state->bit = state->bitmap->bitzero;
2023  funcctx->user_fctx = state;
2024  }
2025 
2026  funcctx = SRF_PERCALL_SETUP();
2027  state = funcctx->user_fctx;
2028 
2029  state->bit = vl_BitmapNextBit(state->bitmap, state->bit, &found);
2030 
2031  if (found) {
2032  datum = Int32GetDatum(state->bit);
2033  state->bit++;
2034  SRF_RETURN_NEXT(funcctx, datum);
2035  }
2036  else {
2037  SRF_RETURN_DONE(funcctx);
2038  }
2039 }
2040 
2041 PG_FUNCTION_INFO_V1(veil_bitmap_hash_range);
2042 /**
2043  * <code>veil_bitmap_hash_range(bmhash text) returns veil_range_t</code>
2044  * Return composite type giving the range of every Bitmap within
2045  * the BitmapHash.
2046  *
2047  * @param fcinfo <code>bmhash text</code> The name of the bitmap array.
2048  * @return <code>veil_range_t</code> Composite type containing the min
2049  * and max values of the bitmap hash's range
2050  */
2051 Datum
2052 veil_bitmap_hash_range(PG_FUNCTION_ARGS)
2053 {
2054  char *name;
2055  BitmapHash *bmhash;
2056 
2057  ensure_init();
2058 
2059  name = strfromtext(PG_GETARG_TEXT_P(0));
2060  bmhash = GetBitmapHash(name, false);
2061 
2062  if (!bmhash) {
2063  ereport(ERROR,
2064  (errcode(ERRCODE_INTERNAL_ERROR),
2065  errmsg("Bitmap Hash %s not defined", name)));
2066  }
2067 
2068  PG_RETURN_DATUM(datum_from_range(bmhash->bitzero, bmhash->bitmax));
2069 }
2070 
2071 
2072 PG_FUNCTION_INFO_V1(veil_bitmap_hash_entries);
2073 /**
2074  * <code>veil_bitmap_hash_entries(bmhash text) returns setof text</code>
2075  * Return the key of every Bitmap within the BitmapHash.
2076  *
2077  * @param fcinfo <code>bmhash text</code> The name of the bitmap hash.
2078  * @return <code>setof text</code> Every key in the hash.
2079  */
2080 Datum
2081 veil_bitmap_hash_entries(PG_FUNCTION_ARGS)
2082 {
2083  struct bitmap_hash_entries_state {
2084  BitmapHash *bmhash;
2085  VarEntry *var;
2086  } *state;
2087  FuncCallContext *funcctx;
2088  MemoryContext oldcontext;
2089  char *name;
2090  Datum datum;
2091  text *result;
2092 
2093  if (SRF_IS_FIRSTCALL())
2094  {
2095  /* Only do this on first call for this result set */
2096  ensure_init();
2097 
2098  funcctx = SRF_FIRSTCALL_INIT();
2099  oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
2100  state = palloc(sizeof(struct bitmap_hash_entries_state));
2101  MemoryContextSwitchTo(oldcontext);
2102 
2103  name = strfromtext(PG_GETARG_TEXT_P(0));
2104  state->bmhash = GetBitmapHash(name, false);
2105 
2106  if (!state->bmhash) {
2107  ereport(ERROR,
2108  (errcode(ERRCODE_INTERNAL_ERROR),
2109  errmsg("Bitmap Hash %s not defined", name)));
2110  }
2111 
2112  state->var = NULL;
2113  funcctx->user_fctx = state;
2114  }
2115 
2116  funcctx = SRF_PERCALL_SETUP();
2117  state = funcctx->user_fctx;
2118 
2119  state->var = vl_NextHashEntry(state->bmhash->hash, state->var);
2120 
2121  if (state->var) {
2122  result = textfromstrn(state->var->key, HASH_KEYLEN);
2123  datum = PointerGetDatum(result);
2124  SRF_RETURN_NEXT(funcctx, datum);
2125  }
2126  else {
2127  SRF_RETURN_DONE(funcctx);
2128  }
2129 }
2130 
2131 
2132 PG_FUNCTION_INFO_V1(veil_int4_set);
2133 /**
2134  * <code>veil_int4_set(name text,value int4) returns int4</code>
2135  * Set an Int4Var variable type to a specified value.
2136  * An Error will be raised if the variable is not defined or is of the
2137  * wrong type.
2138  *
2139  * @param fcinfo <code>name text</code> The name of the int4 variable.
2140  * @param fcinfo <code>value int4</code> The value to be set (may be null).
2141  * @return <code>int4</code> The new value of the variable.
2142  */
2143 Datum
2144 veil_int4_set(PG_FUNCTION_ARGS)
2145 {
2146  char *name;
2147  Int4Var *var;
2148  int32 value;
2149 
2150  ensure_init();
2151 
2152  if (PG_ARGISNULL(0)) {
2153  PG_RETURN_NULL();
2154  }
2155 
2156  name = strfromtext(PG_GETARG_TEXT_P(0));
2157  var = GetInt4Var(name, true);
2158 
2159  if (PG_ARGISNULL(1)) {
2160  var->isnull = true;
2161  PG_RETURN_NULL();
2162  }
2163  else {
2164  value = PG_GETARG_INT32(1);
2165  var->isnull = false;
2166  var->value = value;
2167  PG_RETURN_INT32(value);
2168  }
2169 }
2170 
2171 PG_FUNCTION_INFO_V1(veil_int4_get);
2172 /**
2173  * <code>veil_int4_get(name text) returns int4</code>
2174  * Return the value of an Int4Var variable.
2175  * An Error will be raised if the variable is not defined or is of the
2176  * wrong type.
2177  *
2178  * @param fcinfo <code>name text</code> The name of the int4 variable.
2179  * @return <code>int4</code> The value of the variable.
2180  */
2181 Datum
2182 veil_int4_get(PG_FUNCTION_ARGS)
2183 {
2184  char *name;
2185  Int4Var *var;
2186 
2187  ensure_init();
2188 
2189  name = strfromtext(PG_GETARG_TEXT_P(0));
2190  var = GetInt4Var(name, true);
2191 
2192  if (var->isnull) {
2193  PG_RETURN_NULL();
2194  }
2195  else {
2196  PG_RETURN_INT32(var->value);
2197  }
2198 }
2199 
2200 PG_FUNCTION_INFO_V1(veil_init_int4array);
2201 /**
2202  * <code>veil_init_int4array(arrayname text, range text) returns bool</code>
2203  * Initialise an Int4Array variable. Each entry in the array will be
2204  * zeroed.
2205  *
2206  * @param fcinfo <code>arrayname text</code> The name of the Int4Array variable.
2207  * <br><code>range text</code> Name of the range variable defining the size of
2208  * the array.
2209  * @return <code>bool</code> True
2210  */
2211 Datum
2212 veil_init_int4array(PG_FUNCTION_ARGS)
2213 {
2214  char *array_name;
2215  char *range_name;
2216  VarEntry *array_var;
2217  Int4Array *array;
2218  Range *range;
2219 
2220  ensure_init();
2221 
2222  array_name = strfromtext(PG_GETARG_TEXT_P(0));
2223  array_var = vl_lookup_variable(array_name);
2224  array = GetInt4ArrayFromVar(array_var, true);
2225 
2226  range_name = strfromtext(PG_GETARG_TEXT_P(1));
2227  range = GetRange(range_name, false);
2228 
2229  array = vl_NewInt4Array(array, array_var->shared, range->min, range->max);
2230  array_var->obj = (Object *) array;
2231 
2232  PG_RETURN_BOOL(true);
2233 }
2234 
2235 PG_FUNCTION_INFO_V1(veil_clear_int4array);
2236 /**
2237  * <code>veil_clear_int4array(name text) returns bool</code>
2238  * Clear an Int4Array variable. Each entry in the array will be
2239  * zeroed.
2240  *
2241  * @param fcinfo <code>name text</code> The name of the Int4Array variable.
2242  * @return <code>bool</code> True
2243  */
2244 Datum
2245 veil_clear_int4array(PG_FUNCTION_ARGS)
2246 {
2247  char *array_name;
2248  Int4Array *array;
2249 
2250  ensure_init();
2251 
2252  array_name = strfromtext(PG_GETARG_TEXT_P(0));
2253  array = GetInt4Array(array_name, false);
2254 
2255  vl_ClearInt4Array(array);
2256 
2257  PG_RETURN_BOOL(true);
2258 }
2259 
2260 PG_FUNCTION_INFO_V1(veil_int4array_set);
2261 /**
2262  * <code>veil_int4array_set(array text, idx int4, value int4) returns int4</code>
2263  * Set an Int4Array entry.
2264  *
2265  * @param fcinfo <code>array text</code> The name of the Int4Array variable.
2266  * <br><code>idx int4</code> Index of the entry to be set
2267  * <br><code>value int4</code> Value to which the entry will be set
2268  * @return <code>int4</code> The new value of the array entry
2269  */
2270 Datum
2271 veil_int4array_set(PG_FUNCTION_ARGS)
2272 {
2273  char *array_name;
2274  Int4Array *array;
2275  int32 idx;
2276  int32 value;
2277 
2278  ensure_init();
2279 
2280  array_name = strfromtext(PG_GETARG_TEXT_P(0));
2281  array = GetInt4Array(array_name, false);
2282  idx = PG_GETARG_INT32(1);
2283  value = PG_GETARG_INT32(2);
2284  vl_Int4ArraySet(array, idx, value);
2285 
2286  PG_RETURN_INT32(value);
2287 }
2288 
2289 PG_FUNCTION_INFO_V1(veil_int4array_get);
2290 /**
2291  * <code>veil_int4array_get(array text, idx int4) returns int4</code>
2292  * Get an Int4Array entry.
2293  *
2294  * @param fcinfo <code>array text</code> The name of the Int4Array variable.
2295  * <br><code>idx int4</code> Index of the entry to be retrieved
2296  * @return <code>int4</code> The value of the array entry
2297  */
2298 Datum
2299 veil_int4array_get(PG_FUNCTION_ARGS)
2300 {
2301  char *array_name;
2302  Int4Array *array;
2303  int32 idx;
2304  int32 value;
2305 
2306  ensure_init();
2307 
2308  array_name = strfromtext(PG_GETARG_TEXT_P(0));
2309  array = GetInt4Array(array_name, false);
2310  idx = PG_GETARG_INT32(1);
2311  value = vl_Int4ArrayGet(array, idx);
2312 
2313  PG_RETURN_INT32(value);
2314 }
2315 
2316 
2317 PG_FUNCTION_INFO_V1(veil_init);
2318 /**
2319  * <code>veil_init(doing_reset bool) returns bool</code>
2320  * Initialise or reset a veil session.
2321  * The boolean parameter will be false when called for initialisation,
2322  * and true when performing a reset.
2323  *
2324  * This function may be redefined as a custom function in your
2325  * implementation, or will call initialisation functions registered in
2326  * the table veil.veil_init_fns.
2327  *
2328  * @param fcinfo <code>doing_reset bool</code> Whether we are being
2329  * called in order to reset (true) the session or (false) simply to
2330  * initialise it.
2331  * @return <code>bool</code> True
2332  */
2333 Datum
2334 veil_init(PG_FUNCTION_ARGS)
2335 {
2336  bool param = PG_GETARG_BOOL(0);
2337  int rows = vl_call_init_fns(param);
2338 
2339  if (rows == 0) {
2340  ereport(ERROR,
2341  (errcode(ERRCODE_INTERNAL_ERROR),
2342  errmsg("No user defined veil init functions found"),
2343  errhint("You must redefine veil.veil_init() or register your "
2344  "own init functions in the veil.veil_init_fns table.")));
2345  }
2346  PG_RETURN_BOOL(true);
2347 }
2348 
2349 PG_FUNCTION_INFO_V1(veil_perform_reset);
2350 /**
2351  * <code>veil_perform_reset() returns bool</code>
2352  * Reset veil shared memory for this database. This creates a new
2353  * shared memory context with none of the existing shared variables.
2354  * All current transactions will be able to continue using the current
2355  * variables, all new transactions will see the new set, once this
2356  * function has completed.
2357  *
2358  * @param fcinfo
2359  * @return <code>bool</code> True if the function is able to complete
2360  * successfully. If it is unable, no harm will have been done but
2361  * neither will a memory reset have been performed.
2362  */
2363 Datum
2364 veil_perform_reset(PG_FUNCTION_ARGS)
2365 {
2366  bool success = true;
2367  bool pushed;
2368  bool result;
2369  int ok;
2370 
2371  ensure_init();
2372  ok = vl_spi_connect(&pushed);
2373  if (ok != SPI_OK_CONNECT) {
2374  ereport(ERROR,
2375  (errcode(ERRCODE_INTERNAL_ERROR),
2376  errmsg("failed to perform reset"),
2377  errdetail("SPI_connect() failed, returning %d.", ok)));
2378  }
2379 
2380  success = vl_prepare_context_switch();
2381  if (success) {
2382  result = vl_bool_from_query("select veil.veil_init(TRUE)", &success);
2383  elog(NOTICE, "veil_init returns %s to veil_perform_reset",
2384  success? "true": "false");
2385  success = vl_complete_context_switch();
2386  elog(NOTICE,
2387  "vl_complete_context_switch returns %s to veil_perform_reset",
2388  success? "true": "false");
2389  success &= result;
2390  }
2391  else {
2392  ereport(WARNING,
2393  (errcode(ERRCODE_INTERNAL_ERROR),
2394  errmsg("failed to perform reset"),
2395  errdetail("Unable to prepare for memory reset. "
2396  "Maybe another process is performing a reset, "
2397  "or maybe there is a long-running transaction that "
2398  "is still using the previous memory context.")));
2399  }
2400 
2401  ok = vl_spi_finish(pushed);
2402  PG_RETURN_BOOL(success);
2403 }
2404 
2405 PG_FUNCTION_INFO_V1(veil_force_reset);
2406 /**
2407  * <code>veil_force_reset() returns bool</code>
2408  * Reset veil shared memory for this database, ignoring existing
2409  * transactions. This function will always reset the shared memory
2410  * context, even for sessions that are still using it. Having taken
2411  * this drastic action, it will then cause a panic to reset the server.
2412  *
2413  * Question - won't a panic reset the shared memory in any case? Is the
2414  * panic superfluous, or maybe is this entire function superfluous?
2415  *
2416  * @param fcinfo
2417  * @return <code>bool</code> True.
2418  */
2419 Datum
2420 veil_force_reset(PG_FUNCTION_ARGS)
2421 {
2422  ensure_init();
2424  PG_RETURN_BOOL(true);
2425 }
2426 
2427 
2428 PG_FUNCTION_INFO_V1(veil_version);
2429 /**
2430  * <code>veil_version() returns text</code>
2431  * Return a string describing this version of veil.
2432  *
2433  * @param fcinfo
2434  * @return <code>text</code> String describing the version.
2435  */
2436 Datum
2437 veil_version(PG_FUNCTION_ARGS)
2438 {
2439  char *version_str;
2440  text *version_text;
2441 
2442  version_str = palloc(sizeof(char) * strlen(VEIL_VERSION) +
2443  strlen(VEIL_VERSION_INFO) + 4);
2444  sprintf(version_str, "%s (%s)", VEIL_VERSION, VEIL_VERSION_INFO);
2445 
2446  version_text = textfromstr(version_str);
2447  PG_RETURN_TEXT_P(version_text);
2448 }
2449 
2450 PG_FUNCTION_INFO_V1(veil_serialise);
2451 /**
2452  * <code>veil_serialise(varname text) returns text</code>
2453  * Return a string representing the contents of our variable.
2454  *
2455  * @param fcinfo
2456  * <br><code>varname text</code> Name of the variable to be serialised.
2457  * @return <code>text</code> String containing the serialised variable.
2458  */
2459 Datum
2460 veil_serialise(PG_FUNCTION_ARGS)
2461 {
2462  char *name;
2463  char *result;
2464 
2465  ensure_init();
2466 
2467  if (PG_ARGISNULL(0)) {
2468  PG_RETURN_NULL();
2469  }
2470 
2471  name = strfromtext(PG_GETARG_TEXT_P(0));
2472  result = vl_serialise_var(name);
2473 
2474  if (result) {
2475  PG_RETURN_TEXT_P(textfromstr(result));
2476  }
2477  else {
2478  PG_RETURN_NULL();
2479  }
2480 }
2481 
2482 
2483 PG_FUNCTION_INFO_V1(veil_deserialise);
2484 /**
2485  * <code>veil_deserialise(stream text) returns text</code>
2486  * Create or reset variables based on the output of previous
2487  * veil_serialise calls.
2488  *
2489  * @param fcinfo
2490  * <br><code>stream text</code> Serialised variables string
2491  * @return <code>int4</code> Count of the items de-serialised from
2492  * the string.
2493  */
2494 Datum
2495 veil_deserialise(PG_FUNCTION_ARGS)
2496 {
2497  char *stream;
2498  int32 result;
2499  text *txt;
2500 
2501  ensure_init();
2502 
2503  if (PG_ARGISNULL(0)) {
2504  PG_RETURN_NULL();
2505  }
2506 
2507  txt = PG_GETARG_TEXT_P(0);
2508  stream = strfromtext(txt);
2509  result = vl_deserialise(&stream);
2510 
2511  PG_RETURN_INT32(result);
2512 }
2513 
2514 
veil_variable_t * vl_next_variable(veil_variable_t *prev)
Return the next variable from a scan of the hash of variables.
Datum veil_int4array_get(PG_FUNCTION_ARGS)
veil_int4array_get(array text, idx int4) returns int4 Get an Int4Array entry.
Datum veil_bitmap_from_array(PG_FUNCTION_ARGS)
veil_bitmap_from_array(bmref text, bmarray text, index int4) returns text Place a reference to the sp...
Datum veil_clear_bitmap_hash(PG_FUNCTION_ARGS)
veil_clear_bitmap_hash(bmhash text) returns bool Clear the bits in an existing BitmapHash.
TransactionId xid
The xid for which this variable is valid.
Subtype of Object for storing arrays of integers.
Subtype of Object for storing bitmap refs.
Datum veil_clear_bitmap(PG_FUNCTION_ARGS)
veil_clear_bitmap(name text) returns bool Clear all bits in the specified Bitmap. ...
Subtype of Object for storing bitmaps.
int32 value
the integer value of the variable
static BitmapRef * GetBitmapRef(char *name)
Return the BitmapRef matching the name parameter, possibly creating the VarEntry (variable) for it...
void vl_BitmapIntersect(Bitmap *target, Bitmap *source)
Create the intersection of two bitmaps, updating the first with the result.
Definition: veil_bitmap.c:262
static Range * GetRange(char *name, bool create)
Return the Range variable matching the name parameter, possibly creating the variable.
static text * textfromstr(char *in)
Create a dynamically allocated text value as a copy of a C string.
void vl_NewBitmap(Bitmap **p_bitmap, bool shared, int32 min, int32 max)
Return a newly initialised (empty) Bitmap.
Definition: veil_bitmap.c:95
int32 bitzero
The index of the lowest bit each bitmap can store.
Bitmap * bitmap
Pointer to the referenced bitmap.
int32 bitmax
The index of the highest bit each bitmap can store.
Subtype of Object for storing simple int4 values.
HTAB * vl_get_shared_hash(void)
Return the shared hash for the current context.
Definition: veil_shmem.c:552
ObjType type
This must have the value OBJ_BITMAP.
Describes a veil shared or session variable.
bool shared
Whether this is a shared variable (as opposed to a session variable)
VarEntry * vl_lookup_shared_variable(char *name)
Define a new, or attach to an existing, shared variable.
bool vl_bool_from_query(const char *qry, bool *result)
Executes a query that returns a single bool value.
Definition: veil_query.c:232
void vl_BitmapUnion(Bitmap *target, Bitmap *source)
Create the union of two bitmaps, updating the first with the result.
Definition: veil_bitmap.c:232
Datum veil_bitmap_hash_testbit(PG_FUNCTION_ARGS)
veil_bitmap_hash_testbit(bmhash text, key text, bitno int4) returns bool Test a specified bit within ...
ObjType type
This must have the value OBJ_BITMAP_ARRAY.
Datum veil_bitmap_hash_key_exists(PG_FUNCTION_ARGS)
veil_bitmap_hashkey_exists(bmhash text, key text) returns bool Return true if the key exists in the b...
Datum veil_bitmap_array_setbit(PG_FUNCTION_ARGS)
veil_bitmap_array_setbit(bmarray text, arr_idx int4, bitno int4) returns bool Set a specified bit wit...
char * name
The name of the variable.
Datum veil_clear_bitmap_array(PG_FUNCTION_ARGS)
veil_clear_bitmap_array(bmarray text) returns bool Clear the bits in an existing BitmapArray.
Datum veil_range(PG_FUNCTION_ARGS)
veil_range(name text) returns veil_range_t Return the range (as a SQL veil_range_t composite type) fr...
int32 vl_BitmapNextBit(Bitmap *bitmap, int32 bit, bool *found)
Return the next set bit in the Bitmap.
Definition: veil_bitmap.c:295
bool vl_BitmapTestbit(Bitmap *bitmap, int32 bit)
Test a bit within a Bitmap.
Definition: veil_bitmap.c:210
void vl_ClearBitmap(Bitmap *bitmap)
Clear all bits in a Bitmap.
Definition: veil_bitmap.c:73
static Int4Array * GetInt4ArrayFromVar(VarEntry *var, bool allow_empty)
Return the Int4Array from an Int4Array variable.
int32 vl_Int4ArrayGet(Int4Array *array, int32 idx)
Get an entry from an Int4Array.
Datum veil_bitmap_hash_clearbit(PG_FUNCTION_ARGS)
veil_bitmap_hash_clearbit(bmhash text, key text, bitno int4) returns bool Clear a specified bit withi...
ObjType type
This must have the value OBJ_RANGE.
int32 bitmax
The index of the highest bit the bitmap can store.
static BitmapArray * GetBitmapArrayFromVar(VarEntry *var, bool allow_empty)
Return the BitmapArray from a bitmap array variable.
static Bitmap * GetBitmapFromVar(VarEntry *var, bool allow_empty, bool allow_ref)
Return the Bitmap from a bitmap variable.
Datum veil_bitmap_hash_bits(PG_FUNCTION_ARGS)
veil_bitmap_hash_bits(bmhash text, key text) returns setof int4 Return the set of all bits set in the...
Datum veil_union_from_bitmap_array(PG_FUNCTION_ARGS)
veil_union_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool Union a Bitmap wit...
static char * strfromint(int32 val)
Create a dynamically allocated C string as a copy of an integer value.
static BitmapHash * GetBitmapHashFromVar(VarEntry *var, bool allow_empty)
Return the BitmapHash from a bitmap hash variable.
#define VEIL_VERSION
The version number for this version of veil.
Definition: veil_version.h:16
ObjType type
This must have the value OBJ_INT4_ARRAY.
VarEntry * vl_lookup_variable(char *name)
Lookup a variable by name, creating it as as a session variable if it does not already exist...
Datum veil_bitmap_intersect(PG_FUNCTION_ARGS)
veil_bitmap_intersect(result_name text, name2 text) returns bool Intersect the bitmap specified in pa...
char * vl_serialise_var(char *name)
Serialise a veil variable.
#define HASH_KEYLEN
The key length for veil hash types.
Datum veil_bitmap_array_brange(PG_FUNCTION_ARGS)
veil_bitmap_array_brange(bmarray text) returns veil_range_t Return composite type giving the range of...
Datum veil_force_reset(PG_FUNCTION_ARGS)
veil_force_reset() returns bool Reset veil shared memory for this database, ignoring existing transac...
Datum veil_init_bitmap_array(PG_FUNCTION_ARGS)
veil_init_bitmap_array(text, text, text) returns bool Create or reset a BitmapArray.
Datum veil_init(PG_FUNCTION_ARGS)
veil_init(doing_reset bool) returns bool Initialise or reset a veil session.
Datum veil_init_range(PG_FUNCTION_ARGS)
veil_init_range(name text, min int4, max int4) returns int4 Initialise a Range variable called NAME c...
static char * strfromtext(text *in)
Create a dynamically allocated C string as a copy of a text value.
Datum veil_bitmap_testbit(PG_FUNCTION_ARGS)
veil_bitmap_testbit(name text, bit_number int4) returns bool Test the specified bit in the specified ...
Bitmap * vl_BitmapFromArray(BitmapArray *bmarray, int32 elem)
Return a specified Bitmap from a BitmapArray.
Definition: veil_bitmap.c:321
Datum veil_bitmap_bits(PG_FUNCTION_ARGS)
veil_bitmap_bits(name text) returns setof int4 Return the set of all bits set in the specified Bitmap...
Datum veil_bitmap_array_testbit(PG_FUNCTION_ARGS)
veil_bitmap_array_testbit(bmarray text, arr_idx int4, bitno int4) returns bool Test a specified bit w...
static BitmapArray * GetBitmapArray(char *name, bool allow_empty)
Return the BitmapArray matching the name parameter, possibly creating the (VarEntry) variable...
void vl_NewBitmapHash(BitmapHash **p_bmhash, char *name, int32 bitzero, int32 bitmax)
Return a newly initialised (empty) BitmapHash.
Definition: veil_bitmap.c:499
Datum veil_bitmap_array_bits(PG_FUNCTION_ARGS)
veil_bitmap_array_bits(bmarray text, arr_idx int4) returns setof int4 Return the set of all bits set ...
Datum veil_bitmap_clearbit(PG_FUNCTION_ARGS)
veil_bitmap_clearbit(name int4, bit_number text) returns bool Clear the specified bit in the specifie...
int32 arraymax
The index of the lowest numbered bitmap in the array.
static Int4Var * GetInt4Var(char *name, bool create)
Return the Int4Var variable matching the name parameter, possibly creating the variable.
bool vl_prepare_context_switch(void)
Prepare for a switch to the alternate context.
Definition: veil_shmem.c:604
static BitmapRef * GetBitmapRefFromVar(VarEntry *var)
Return the BitmapRef from a bitmap ref variable.
void vl_BitmapSetbit(Bitmap *bitmap, int32 bit)
Set a bit within a Bitmap.
Definition: veil_bitmap.c:151
Datum veil_variables(PG_FUNCTION_ARGS)
veil_variables() returns setof veil_variable_t Return a veil_variable_t record for each defined varia...
Provide definitions for all non-local C-callable Veil functions.
static Int4Array * GetInt4Array(char *name, bool allow_empty)
Return the Int4Array matching the name parameter, possibly creating the VarEntry (variable) for it...
Datum veil_intersect_from_bitmap_array(PG_FUNCTION_ARGS)
veil_intersect_from_bitmap_array(bitmap text, bmarray text, arr_idx int4) returns bool Intersect a Bi...
int vl_spi_finish(bool pushed)
Reciprocal function for vl_spi_connect()
Definition: veil_query.c:62
bool shared
Whether this is a shared variable.
General purpose object-type.
Provides version information for veil.
Datum veil_init_bitmap(PG_FUNCTION_ARGS)
veil_init_bitmap(bitmap_name text, range_nametext) returns bool Create or re-initialise a Bitmap...
int32 bitzero
The index of the lowest bit the bitmap can store.
static BitmapHash * GetBitmapHash(char *name, bool allow_empty)
Return the BitmapHash matching the name parameter, possibly creating the VarEntry (variable) for it...
Subtype of Object for storing bitmap hashes.
Datum veil_bitmap_from_hash(PG_FUNCTION_ARGS)
veil_bitmap_from_hash(bmref text, bmhash text, key text) returns text Place a reference to the specif...
Datum veil_intersect_from_bitmap_hash(PG_FUNCTION_ARGS)
veil_intersect_from_bitmap_hash(bitmap text, bmhash text, key text) returns bool Intersect a Bitmap w...
char * type
The type of the variable (eg "Bitmap")
ObjType
Describes the type of an Object record or one of its subtypes.
void vl_ClearInt4Array(Int4Array *array)
Reset all Int4 entries in an Int4Array (to zero).
Bitmap * vl_BitmapFromHash(BitmapHash *bmhash, char *hashelem)
Return a specified Bitmap from a BitmapHash.
Definition: veil_bitmap.c:548
static Bitmap * GetBitmap(char *name, bool allow_empty, bool allow_ref)
Return the Bitmap matching the name parameter, possibly creating the VarEntry (variable) for it...
A Veil variable.
static char * copystr(char *str)
Create a dynamically allocated text value as a copy of a C string, applying a limit to the length...
Bitmap * vl_AddBitmapToHash(BitmapHash *bmhash, char *hashelem)
Create a newly allocated empty Bitmap to a BitmapHash.
Definition: veil_bitmap.c:588
VarEntry * vl_NextHashEntry(HTAB *hash, VarEntry *prev)
Utility function for scanning the hash table of a BitmapHash.
Definition: veil_bitmap.c:474
Int4Array * vl_NewInt4Array(Int4Array *current, bool shared, int32 min, int32 max)
Return a newly initialised (zeroed) Int4Array.
Datum veil_bitmap_hash_setbit(PG_FUNCTION_ARGS)
veil_bitmap_hash_setbit(bmhash text, key text, bitno int4) returns bool Set a specified bit within a ...
Datum veil_int4array_set(PG_FUNCTION_ARGS)
veil_int4array_set(array text, idx int4, value int4) returns int4 Set an Int4Array entry...
ObjType type
This must have the value OBJ_BITMAP_REF.
int32 arrayzero
The index of array element zero: the index of the lowest numbered bitmap in the array.
Datum veil_bitmap_array_arange(PG_FUNCTION_ARGS)
veil_bitmap_array_arange(bmarray text) returns veil_range_t Return composite type giving the range of...
void vl_type_mismatch(char *name, ObjType expected, ObjType got)
Report, by raising an error, a type mismatch between the expected and actual type of a VarEntry varia...
Subtype of Object for storing range values.
int32 max
Upper limit for range.
void vl_ClearBitmapArray(BitmapArray *bmarray)
Clear all bitmaps in the given BitmapArray.
Definition: veil_bitmap.c:341
void vl_NewBitmapArray(BitmapArray **p_bmarray, bool shared, int32 arrayzero, int32 arraymax, int32 bitzero, int32 bitmax)
Return a newly initialised (empty) BitmapArray.
Definition: veil_bitmap.c:368
Datum veil_init_bitmap_hash(PG_FUNCTION_ARGS)
veil_init_bitmap_hash(bmhash text, range text) returns bool Create or reset a BitmapHash.
Datum veil_bitmap_hash_entries(PG_FUNCTION_ARGS)
veil_bitmap_hash_entries(bmhash text) returns setof text Return the key of every Bitmap within the Bi...
void vl_Int4ArraySet(Int4Array *array, int32 idx, int32 value)
Set an entry within an Int4Array.
Datum veil_bitmap_union(PG_FUNCTION_ARGS)
veil_bitmap_union(result_name text, name2 text) returns bool Union the bitmap specified in parameter ...
Datum veil_init_int4array(PG_FUNCTION_ARGS)
veil_init_int4array(arrayname text, range text) returns bool Initialise an Int4Array variable...
void vl_force_context_switch(void)
In desparation, if we are unable to complete a context switch, we should use this function...
Definition: veil_shmem.c:719
int32 bitzero
The index of the lowest bit each bitmap can store.
void * vl_malloc(size_t size)
Dynamically allocate memory using palloc in TopMemoryContext.
Definition: veil_utils.c:28
static void ensure_init()
Perform session initialisation once for the session.
Datum veil_union_into_bitmap_hash(PG_FUNCTION_ARGS)
veil_union_into_bitmap_hash(bmhash text, key text, bitmap text) returns bool Union a Bitmap with the ...
Datum veil_bitmap_setbit(PG_FUNCTION_ARGS)
veil_bitmap_setbit(name text, bit_number int4) returns bool Set the specified bit in the specified Bi...
int32 bitmax
The index of the highest bit each bitmap can store.
ObjType type
This must have the value OBJ_BITMAP_HASH.
Datum veil_perform_reset(PG_FUNCTION_ARGS)
veil_perform_reset() returns bool Reset veil shared memory for this database.
Object * obj
Pointer to the contents of the variable.
Datum veil_union_from_bitmap_hash(PG_FUNCTION_ARGS)
veil_union_from_bitmap_hash(bmhash text, key text, bitmap text) returns bool Union a Bitmap with the ...
Subtype of Object for storing bitmap arrays.
int vl_call_init_fns(bool param)
Identify any registered init_functions and execute them.
Definition: veil_query.c:336
int vl_spi_connect(bool *p_pushed)
If already connected in this session, push the current connection, and get a new one.
Definition: veil_query.c:46
static text * textfromstrn(char *in, int limit)
Create a dynamically allocated text value as a copy of a C string, applying a limit to the length...
Int4Var * vl_NewInt4(bool shared)
Create a new session or shared Int4Var object.
ObjType type
This must have the value OBJ_INT4.
Datum veil_int4_set(PG_FUNCTION_ARGS)
veil_int4_set(name text,value int4) returns int4 Set an Int4Var variable type to a specified value...
int32 vl_deserialise(char **p_stream)
De-serialise a base64 string containing, possibly many, derialised veil variables.
Datum veil_bitmap_hash_range(PG_FUNCTION_ARGS)
veil_bitmap_hash_range(bmhash text) returns veil_range_t Return composite type giving the range of ev...
int32 min
Lower limit for range.
Datum veil_version(PG_FUNCTION_ARGS)
veil_version() returns text Return a string describing this version of veil.
static char * strfrombool(bool val)
Create a dynamically allocated C string as a copy of a boolean value.
bool isnull
if true, the value is null
static Datum datum_from_range(int64 min, int64 max)
Create a datum containing the values of a veil_range_t composite type.
Datum veil_serialise(PG_FUNCTION_ARGS)
veil_serialise(varname text) returns text Return a string representing the contents of our variable...
Datum veil_bitmap_array_clearbit(PG_FUNCTION_ARGS)
veil_bitmap_array_clearbit(bmarray text, arr_idx int4, bitno int4) returns bool Clear a specified bit...
Datum veil_deserialise(PG_FUNCTION_ARGS)
veil_deserialise(stream text) returns text Create or reset variables based on the output of previous ...
bool vl_BitmapHashHasKey(BitmapHash *bmhash, char *hashelem)
Determine whether the supplied key exists in the BitmapHash.
Definition: veil_bitmap.c:629
Datum veil_int4_get(PG_FUNCTION_ARGS)
veil_int4_get(name text) returns int4 Return the value of an Int4Var variable.
Datum veil_clear_int4array(PG_FUNCTION_ARGS)
veil_clear_int4array(name text) returns bool Clear an Int4Array variable.
bool vl_complete_context_switch(void)
Complete the context switch started by vl_prepare_context_switch().
Definition: veil_shmem.c:678
Datum veil_bitmap_range(PG_FUNCTION_ARGS)
veil_bitmap_range(name text) returns veil_range_t Return composite type giving the range of the speci...
#define VEIL_VERSION_INFO
The version number suffix, indicating stability.
Definition: veil_version.h:19
char key[60]
String containing variable name.
char * vl_ObjTypeName(ObjType obj)
Return a static string describing an ObjType object.
Definition: veil_utils.c:45
Range * vl_NewRange(bool shared)
Create a new session or shared Range object.
void vl_BitmapClearbit(Bitmap *bitmap, int32 bit)
Clear a bit within a Bitmap.
Definition: veil_bitmap.c:181
Define all Veil public datatypes.
Datum veil_share(PG_FUNCTION_ARGS)
veil_share(name text) returns bool Define a shared variable called NAME, returning true...