reloptions.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*-------------------------------------------------------------------------
  2. *
  3. * reloptions.h
  4. * Core support for relation and tablespace options (pg_class.reloptions
  5. * and pg_tablespace.spcoptions)
  6. *
  7. * Note: the functions dealing with text-array reloptions values declare
  8. * them as Datum, not ArrayType *, to avoid needing to include array.h
  9. * into a lot of low-level code.
  10. *
  11. *
  12. * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
  13. * Portions Copyright (c) 1994, Regents of the University of California
  14. *
  15. * src/include/access/reloptions.h
  16. *
  17. *-------------------------------------------------------------------------
  18. */
  19. #ifndef RELOPTIONS_H
  20. #define RELOPTIONS_H
  21. #include "access/amapi.h"
  22. #include "access/htup.h"
  23. #include "access/tupdesc.h"
  24. #include "nodes/pg_list.h"
  25. #include "storage/lock.h"
  26. /* types supported by reloptions */
  27. typedef enum relopt_type
  28. {
  29. RELOPT_TYPE_BOOL,
  30. RELOPT_TYPE_INT,
  31. RELOPT_TYPE_REAL,
  32. RELOPT_TYPE_STRING
  33. } relopt_type;
  34. /* kinds supported by reloptions */
  35. typedef enum relopt_kind
  36. {
  37. RELOPT_KIND_HEAP = (1 << 0),
  38. RELOPT_KIND_TOAST = (1 << 1),
  39. RELOPT_KIND_BTREE = (1 << 2),
  40. RELOPT_KIND_HASH = (1 << 3),
  41. RELOPT_KIND_GIN = (1 << 4),
  42. RELOPT_KIND_GIST = (1 << 5),
  43. RELOPT_KIND_ATTRIBUTE = (1 << 6),
  44. RELOPT_KIND_TABLESPACE = (1 << 7),
  45. RELOPT_KIND_SPGIST = (1 << 8),
  46. RELOPT_KIND_VIEW = (1 << 9),
  47. RELOPT_KIND_BRIN = (1 << 10),
  48. /* if you add a new kind, make sure you update "last_default" too */
  49. RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_BRIN,
  50. /* some compilers treat enums as signed ints, so we can't use 1 << 31 */
  51. RELOPT_KIND_MAX = (1 << 30)
  52. } relopt_kind;
  53. /* reloption namespaces allowed for heaps -- currently only TOAST */
  54. #define HEAP_RELOPT_NAMESPACES { "toast", NULL }
  55. /* generic struct to hold shared data */
  56. typedef struct relopt_gen
  57. {
  58. const char *name; /* must be first (used as list termination
  59. * marker) */
  60. const char *desc;
  61. bits32 kinds;
  62. LOCKMODE lockmode;
  63. int namelen;
  64. relopt_type type;
  65. } relopt_gen;
  66. /* holds a parsed value */
  67. typedef struct relopt_value
  68. {
  69. relopt_gen *gen;
  70. bool isset;
  71. union
  72. {
  73. bool bool_val;
  74. int int_val;
  75. double real_val;
  76. char *string_val; /* allocated separately */
  77. } values;
  78. } relopt_value;
  79. /* reloptions records for specific variable types */
  80. typedef struct relopt_bool
  81. {
  82. relopt_gen gen;
  83. bool default_val;
  84. } relopt_bool;
  85. typedef struct relopt_int
  86. {
  87. relopt_gen gen;
  88. int default_val;
  89. int min;
  90. int max;
  91. } relopt_int;
  92. typedef struct relopt_real
  93. {
  94. relopt_gen gen;
  95. double default_val;
  96. double min;
  97. double max;
  98. } relopt_real;
  99. /* validation routines for strings */
  100. typedef void (*validate_string_relopt) (char *value);
  101. typedef struct relopt_string
  102. {
  103. relopt_gen gen;
  104. int default_len;
  105. bool default_isnull;
  106. validate_string_relopt validate_cb;
  107. char *default_val;
  108. } relopt_string;
  109. /* This is the table datatype for fillRelOptions */
  110. typedef struct
  111. {
  112. const char *optname; /* option's name */
  113. relopt_type opttype; /* option's datatype */
  114. int offset; /* offset of field in result struct */
  115. } relopt_parse_elt;
  116. /*
  117. * These macros exist for the convenience of amoptions writers (but consider
  118. * using fillRelOptions, which is a lot simpler). Beware of multiple
  119. * evaluation of arguments!
  120. *
  121. * The last argument in the HANDLE_*_RELOPTION macros allows the caller to
  122. * determine whether the option was set (true), or its value acquired from
  123. * defaults (false); it can be passed as (char *) NULL if the caller does not
  124. * need this information.
  125. *
  126. * optname is the option name (a string), var is the variable
  127. * on which the value should be stored (e.g. StdRdOptions->fillfactor), and
  128. * option is a relopt_value pointer.
  129. *
  130. * The normal way to use this is to loop on the relopt_value array returned by
  131. * parseRelOptions:
  132. * for (i = 0; options[i].gen->name; i++)
  133. * {
  134. * if (HAVE_RELOPTION("fillfactor", options[i])
  135. * {
  136. * HANDLE_INT_RELOPTION("fillfactor", rdopts->fillfactor, options[i], &isset);
  137. * continue;
  138. * }
  139. * if (HAVE_RELOPTION("default_row_acl", options[i])
  140. * {
  141. * ...
  142. * }
  143. * ...
  144. * if (validate)
  145. * ereport(ERROR,
  146. * (errmsg("unknown option")));
  147. * }
  148. *
  149. * Note that this is more or less the same that fillRelOptions does, so only
  150. * use this if you need to do something non-standard within some option's
  151. * code block.
  152. */
  153. #define HAVE_RELOPTION(optname, option) \
  154. (pg_strncasecmp(option.gen->name, optname, option.gen->namelen + 1) == 0)
  155. #define HANDLE_INT_RELOPTION(optname, var, option, wasset) \
  156. do { \
  157. if (option.isset) \
  158. var = option.values.int_val; \
  159. else \
  160. var = ((relopt_int *) option.gen)->default_val; \
  161. (wasset) != NULL ? *(wasset) = option.isset : (dummyret)NULL; \
  162. } while (0)
  163. #define HANDLE_BOOL_RELOPTION(optname, var, option, wasset) \
  164. do { \
  165. if (option.isset) \
  166. var = option.values.bool_val; \
  167. else \
  168. var = ((relopt_bool *) option.gen)->default_val; \
  169. (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
  170. } while (0)
  171. #define HANDLE_REAL_RELOPTION(optname, var, option, wasset) \
  172. do { \
  173. if (option.isset) \
  174. var = option.values.real_val; \
  175. else \
  176. var = ((relopt_real *) option.gen)->default_val; \
  177. (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
  178. } while (0)
  179. /*
  180. * Note that this assumes that the variable is already allocated at the tail of
  181. * reloptions structure (StdRdOptions or equivalent).
  182. *
  183. * "base" is a pointer to the reloptions structure, and "offset" is an integer
  184. * variable that must be initialized to sizeof(reloptions structure). This
  185. * struct must have been allocated with enough space to hold any string option
  186. * present, including terminating \0 for every option. SET_VARSIZE() must be
  187. * called on the struct with this offset as the second argument, after all the
  188. * string options have been processed.
  189. */
  190. #define HANDLE_STRING_RELOPTION(optname, var, option, base, offset, wasset) \
  191. do { \
  192. relopt_string *optstring = (relopt_string *) option.gen;\
  193. char *string_val; \
  194. if (option.isset) \
  195. string_val = option.values.string_val; \
  196. else if (!optstring->default_isnull) \
  197. string_val = optstring->default_val; \
  198. else \
  199. string_val = NULL; \
  200. (wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
  201. if (string_val == NULL) \
  202. var = 0; \
  203. else \
  204. { \
  205. strcpy(((char *)(base)) + (offset), string_val); \
  206. var = (offset); \
  207. (offset) += strlen(string_val) + 1; \
  208. } \
  209. } while (0)
  210. /*
  211. * For use during amoptions: get the strlen of a string option
  212. * (either default or the user defined value)
  213. */
  214. #define GET_STRING_RELOPTION_LEN(option) \
  215. ((option).isset ? strlen((option).values.string_val) : \
  216. ((relopt_string *) (option).gen)->default_len)
  217. /*
  218. * For use by code reading options already parsed: get a pointer to the string
  219. * value itself. "optstruct" is the StdRdOption struct or equivalent, "member"
  220. * is the struct member corresponding to the string option
  221. */
  222. #define GET_STRING_RELOPTION(optstruct, member) \
  223. ((optstruct)->member == 0 ? NULL : \
  224. (char *)(optstruct) + (optstruct)->member)
  225. extern relopt_kind add_reloption_kind(void);
  226. extern void add_bool_reloption(bits32 kinds, char *name, char *desc,
  227. bool default_val);
  228. extern void add_int_reloption(bits32 kinds, char *name, char *desc,
  229. int default_val, int min_val, int max_val);
  230. extern void add_real_reloption(bits32 kinds, char *name, char *desc,
  231. double default_val, double min_val, double max_val);
  232. extern void add_string_reloption(bits32 kinds, char *name, char *desc,
  233. char *default_val, validate_string_relopt validator);
  234. extern Datum transformRelOptions(Datum oldOptions, List *defList,
  235. char *namspace, char *validnsps[],
  236. bool ignoreOids, bool isReset);
  237. extern List *untransformRelOptions(Datum options);
  238. extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
  239. amoptions_function amoptions);
  240. extern relopt_value *parseRelOptions(Datum options, bool validate,
  241. relopt_kind kind, int *numrelopts);
  242. extern void *allocateReloptStruct(Size base, relopt_value *options,
  243. int numoptions);
  244. extern void fillRelOptions(void *rdopts, Size basesize,
  245. relopt_value *options, int numoptions,
  246. bool validate,
  247. const relopt_parse_elt *elems, int nelems);
  248. extern bytea *default_reloptions(Datum reloptions, bool validate,
  249. relopt_kind kind);
  250. extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate);
  251. extern bytea *view_reloptions(Datum reloptions, bool validate);
  252. extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions,
  253. bool validate);
  254. extern bytea *attribute_reloptions(Datum reloptions, bool validate);
  255. extern bytea *tablespace_reloptions(Datum reloptions, bool validate);
  256. extern LOCKMODE AlterTableGetRelOptionsLockLevel(List *defList);
  257. #endif /* RELOPTIONS_H */