2
0

arrayaccess.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*-------------------------------------------------------------------------
  2. *
  3. * arrayaccess.h
  4. * Declarations for element-by-element access to Postgres arrays.
  5. *
  6. *
  7. * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
  8. * Portions Copyright (c) 1994, Regents of the University of California
  9. *
  10. * src/include/utils/arrayaccess.h
  11. *
  12. *-------------------------------------------------------------------------
  13. */
  14. #ifndef ARRAYACCESS_H
  15. #define ARRAYACCESS_H
  16. #include "access/tupmacs.h"
  17. #include "utils/array.h"
  18. /*
  19. * Functions for iterating through elements of a flat or expanded array.
  20. * These require a state struct "array_iter iter".
  21. *
  22. * Use "array_iter_setup(&iter, arrayptr);" to prepare to iterate, and
  23. * "datumvar = array_iter_next(&iter, &isnullvar, index, ...);" to fetch
  24. * the next element into datumvar/isnullvar.
  25. * "index" must be the zero-origin element number; we make caller provide
  26. * this since caller is generally counting the elements anyway. Despite
  27. * that, these functions can only fetch elements sequentially.
  28. */
  29. typedef struct array_iter
  30. {
  31. /* datumptr being NULL or not tells if we have flat or expanded array */
  32. /* Fields used when we have an expanded array */
  33. Datum *datumptr; /* Pointer to Datum array */
  34. bool *isnullptr; /* Pointer to isnull array */
  35. /* Fields used when we have a flat array */
  36. char *dataptr; /* Current spot in the data area */
  37. bits8 *bitmapptr; /* Current byte of the nulls bitmap, or NULL */
  38. int bitmask; /* mask for current bit in nulls bitmap */
  39. } array_iter;
  40. static inline void
  41. array_iter_setup(array_iter *it, AnyArrayType *a)
  42. {
  43. if (VARATT_IS_EXPANDED_HEADER(a))
  44. {
  45. if (a->xpn.dvalues)
  46. {
  47. it->datumptr = a->xpn.dvalues;
  48. it->isnullptr = a->xpn.dnulls;
  49. /* we must fill all fields to prevent compiler warnings */
  50. it->dataptr = NULL;
  51. it->bitmapptr = NULL;
  52. }
  53. else
  54. {
  55. /* Work with flat array embedded in the expanded datum */
  56. it->datumptr = NULL;
  57. it->isnullptr = NULL;
  58. it->dataptr = ARR_DATA_PTR(a->xpn.fvalue);
  59. it->bitmapptr = ARR_NULLBITMAP(a->xpn.fvalue);
  60. }
  61. }
  62. else
  63. {
  64. it->datumptr = NULL;
  65. it->isnullptr = NULL;
  66. it->dataptr = ARR_DATA_PTR((ArrayType *) a);
  67. it->bitmapptr = ARR_NULLBITMAP((ArrayType *) a);
  68. }
  69. it->bitmask = 1;
  70. }
  71. static inline Datum
  72. array_iter_next(array_iter *it, bool *isnull, int i,
  73. int elmlen, bool elmbyval, char elmalign)
  74. {
  75. Datum ret;
  76. if (it->datumptr)
  77. {
  78. ret = it->datumptr[i];
  79. *isnull = it->isnullptr ? it->isnullptr[i] : false;
  80. }
  81. else
  82. {
  83. if (it->bitmapptr && (*(it->bitmapptr) & it->bitmask) == 0)
  84. {
  85. *isnull = true;
  86. ret = (Datum) 0;
  87. }
  88. else
  89. {
  90. *isnull = false;
  91. ret = fetch_att(it->dataptr, elmbyval, elmlen);
  92. it->dataptr = att_addlength_pointer(it->dataptr, elmlen,
  93. it->dataptr);
  94. it->dataptr = (char *) att_align_nominal(it->dataptr, elmalign);
  95. }
  96. it->bitmask <<= 1;
  97. if (it->bitmask == 0x100)
  98. {
  99. if (it->bitmapptr)
  100. it->bitmapptr++;
  101. it->bitmask = 1;
  102. }
  103. }
  104. return ret;
  105. }
  106. #endif /* ARRAYACCESS_H */