2006-07-04 00:45:41 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* reloptions.h
|
|
|
|
* Core support for relation options (pg_class.reloptions)
|
|
|
|
*
|
|
|
|
* Note: the functions dealing with text-array reloptions values declare
|
|
|
|
* them as Datum, not ArrayType *, to avoid needing to include array.h
|
|
|
|
* into a lot of low-level code.
|
|
|
|
*
|
|
|
|
*
|
2009-01-01 18:24:05 +01:00
|
|
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
2006-07-04 00:45:41 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2009-01-12 22:02:15 +01:00
|
|
|
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.10 2009/01/12 21:02:15 alvherre Exp $
|
2006-07-04 00:45:41 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef RELOPTIONS_H
|
|
|
|
#define RELOPTIONS_H
|
|
|
|
|
|
|
|
#include "nodes/pg_list.h"
|
|
|
|
|
2009-01-05 18:14:28 +01:00
|
|
|
/* types supported by reloptions */
|
|
|
|
typedef enum relopt_type
|
|
|
|
{
|
|
|
|
RELOPT_TYPE_BOOL,
|
|
|
|
RELOPT_TYPE_INT,
|
|
|
|
RELOPT_TYPE_REAL,
|
|
|
|
RELOPT_TYPE_STRING
|
|
|
|
} relopt_type;
|
|
|
|
|
|
|
|
/* kinds supported by reloptions */
|
|
|
|
typedef enum relopt_kind
|
|
|
|
{
|
|
|
|
RELOPT_KIND_HEAP,
|
|
|
|
/* XXX do we need a separate kind for TOAST tables? */
|
|
|
|
RELOPT_KIND_BTREE,
|
|
|
|
RELOPT_KIND_HASH,
|
|
|
|
RELOPT_KIND_GIN,
|
|
|
|
RELOPT_KIND_GIST,
|
|
|
|
/* if you add a new kind, make sure you update "last_default" too */
|
|
|
|
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_GIST,
|
|
|
|
RELOPT_KIND_MAX = 255
|
|
|
|
} relopt_kind;
|
|
|
|
|
|
|
|
/* generic struct to hold shared data */
|
|
|
|
typedef struct relopt_gen
|
|
|
|
{
|
|
|
|
const char *name; /* must be first (used as list termination marker) */
|
|
|
|
const char *desc;
|
|
|
|
relopt_kind kind;
|
|
|
|
int namelen;
|
|
|
|
relopt_type type;
|
|
|
|
} relopt_gen;
|
|
|
|
|
|
|
|
/* holds a parsed value */
|
|
|
|
typedef struct relopt_value
|
|
|
|
{
|
|
|
|
relopt_gen *gen;
|
|
|
|
bool isset;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
bool bool_val;
|
|
|
|
int int_val;
|
|
|
|
double real_val;
|
|
|
|
char *string_val; /* allocated separately */
|
|
|
|
} values;
|
|
|
|
} relopt_value;
|
|
|
|
|
|
|
|
/* reloptions records for specific variable types */
|
|
|
|
typedef struct relopt_bool
|
|
|
|
{
|
|
|
|
relopt_gen gen;
|
|
|
|
bool default_val;
|
|
|
|
} relopt_bool;
|
2009-01-12 22:02:15 +01:00
|
|
|
|
2009-01-05 18:14:28 +01:00
|
|
|
typedef struct relopt_int
|
|
|
|
{
|
|
|
|
relopt_gen gen;
|
|
|
|
int default_val;
|
|
|
|
int min;
|
|
|
|
int max;
|
|
|
|
} relopt_int;
|
|
|
|
|
|
|
|
typedef struct relopt_real
|
|
|
|
{
|
|
|
|
relopt_gen gen;
|
|
|
|
double default_val;
|
|
|
|
double min;
|
|
|
|
double max;
|
|
|
|
} relopt_real;
|
|
|
|
|
2009-01-12 22:02:15 +01:00
|
|
|
/* validation routines for strings */
|
|
|
|
typedef void (*validate_string_relopt) (char *value);
|
2009-01-08 20:34:41 +01:00
|
|
|
|
2009-01-05 18:14:28 +01:00
|
|
|
typedef struct relopt_string
|
|
|
|
{
|
|
|
|
relopt_gen gen;
|
|
|
|
int default_len;
|
|
|
|
bool default_isnull;
|
2009-01-08 20:34:41 +01:00
|
|
|
validate_string_relopt validate_cb;
|
2009-01-12 22:02:15 +01:00
|
|
|
char default_val[1]; /* variable length, zero-terminated */
|
2009-01-05 18:14:28 +01:00
|
|
|
} relopt_string;
|
|
|
|
|
2009-01-12 22:02:15 +01:00
|
|
|
/* This is the input type for fillRelOptions */
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
char *optname;
|
|
|
|
relopt_type opttype;
|
|
|
|
int offset;
|
|
|
|
} relopt_parse_elt;
|
|
|
|
|
|
|
|
|
2009-01-05 18:14:28 +01:00
|
|
|
/*
|
2009-01-12 22:02:15 +01:00
|
|
|
* These macros exist for the convenience of amoptions writers (but consider
|
|
|
|
* using fillRelOptions, which is a lot simpler). Beware of multiple
|
|
|
|
* evaluation of arguments!
|
2009-01-06 15:47:37 +01:00
|
|
|
*
|
|
|
|
* The last argument in the HANDLE_*_RELOPTION macros allows the caller to
|
|
|
|
* determine whether the option was set (true), or its value acquired from
|
|
|
|
* defaults (false); it can be passed as (char *) NULL if the caller does not
|
|
|
|
* need this information.
|
2009-01-12 22:02:15 +01:00
|
|
|
*
|
|
|
|
* optname is the option name (a string), var is the variable
|
|
|
|
* on which the value should be stored (e.g. StdRdOptions->fillfactor), and
|
|
|
|
* option is a relopt_value pointer.
|
|
|
|
*
|
|
|
|
* The normal way to use this is to loop on the relopt_value array returned by
|
|
|
|
* parseRelOptions:
|
|
|
|
* for (i = 0; options[i].gen->name; i++)
|
|
|
|
* {
|
|
|
|
* if (HAVE_RELOPTION("fillfactor", options[i])
|
|
|
|
* {
|
|
|
|
* HANDLE_INT_RELOPTION("fillfactor", rdopts->fillfactor, options[i], &isset);
|
|
|
|
* continue;
|
|
|
|
* }
|
|
|
|
* if (HAVE_RELOPTION("default_row_acl", options[i])
|
|
|
|
* {
|
|
|
|
* ...
|
|
|
|
* }
|
|
|
|
* ...
|
|
|
|
* if (validate)
|
|
|
|
* ereport(ERROR,
|
|
|
|
* (errmsg("unknown option")));
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* Note that this is more or less the same that fillRelOptions does, so only
|
|
|
|
* use this if you need to do something non-standard within some options'
|
|
|
|
* block.
|
2009-01-05 18:14:28 +01:00
|
|
|
*/
|
|
|
|
#define HAVE_RELOPTION(optname, option) \
|
2009-01-08 20:34:41 +01:00
|
|
|
(pg_strncasecmp(option.gen->name, optname, option.gen->namelen + 1) == 0)
|
2009-01-05 18:14:28 +01:00
|
|
|
|
2009-01-12 22:02:15 +01:00
|
|
|
#define HANDLE_INT_RELOPTION(optname, var, option, wasset) \
|
|
|
|
do { \
|
|
|
|
if (option.isset) \
|
|
|
|
var = option.values.int_val; \
|
|
|
|
else \
|
|
|
|
var = ((relopt_int *) option.gen)->default_val; \
|
|
|
|
(wasset) != NULL ? *(wasset) = option.isset : (dummyret)NULL; \
|
2009-01-05 18:14:28 +01:00
|
|
|
} while (0)
|
|
|
|
|
2009-01-06 15:47:37 +01:00
|
|
|
#define HANDLE_BOOL_RELOPTION(optname, var, option, wasset) \
|
2009-01-05 18:14:28 +01:00
|
|
|
do { \
|
2009-01-12 22:02:15 +01:00
|
|
|
if (option.isset) \
|
|
|
|
var = option.values.bool_val; \
|
|
|
|
else \
|
|
|
|
var = ((relopt_bool *) option.gen)->default_val; \
|
|
|
|
(wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
|
2009-01-05 18:14:28 +01:00
|
|
|
} while (0)
|
|
|
|
|
2009-01-12 22:02:15 +01:00
|
|
|
#define HANDLE_REAL_RELOPTION(optname, var, option, wasset) \
|
|
|
|
do { \
|
|
|
|
if (option.isset) \
|
|
|
|
var = option.values.real_val; \
|
|
|
|
else \
|
|
|
|
var = ((relopt_real *) option.gen)->default_val; \
|
|
|
|
(wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
|
2009-01-05 18:14:28 +01:00
|
|
|
} while (0)
|
|
|
|
|
2009-01-06 15:47:37 +01:00
|
|
|
/*
|
|
|
|
* Note that this assumes that the variable is already allocated at the tail of
|
2009-01-12 22:02:15 +01:00
|
|
|
* reloptions structure (StdRdOptions or equivalent).
|
2009-01-06 15:47:37 +01:00
|
|
|
*
|
|
|
|
* "base" is a pointer to the reloptions structure, and "offset" is an integer
|
|
|
|
* variable that must be initialized to sizeof(reloptions structure). This
|
|
|
|
* struct must have been allocated with enough space to hold any string option
|
|
|
|
* present, including terminating \0 for every option. SET_VARSIZE() must be
|
|
|
|
* called on the struct with this offset as the second argument, after all the
|
|
|
|
* string options have been processed.
|
|
|
|
*/
|
|
|
|
#define HANDLE_STRING_RELOPTION(optname, var, option, base, offset, wasset) \
|
2009-01-08 20:34:41 +01:00
|
|
|
do { \
|
2009-01-12 22:02:15 +01:00
|
|
|
relopt_string *optstring = (relopt_string *) option.gen;\
|
|
|
|
char *string_val; \
|
|
|
|
if (option.isset) \
|
|
|
|
string_val = option.values.string_val; \
|
|
|
|
else if (!optstring->default_isnull) \
|
|
|
|
string_val = optstring->default_val; \
|
|
|
|
else \
|
|
|
|
string_val = NULL; \
|
|
|
|
(wasset) != NULL ? *(wasset) = option.isset : (dummyret) NULL; \
|
|
|
|
if (string_val == NULL) \
|
|
|
|
var = 0; \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
strcpy(((char *)(base)) + (offset), string_val); \
|
|
|
|
var = (offset); \
|
|
|
|
(offset) += strlen(string_val) + 1; \
|
|
|
|
} \
|
2009-01-05 18:14:28 +01:00
|
|
|
} while (0)
|
|
|
|
|
2009-01-08 20:34:41 +01:00
|
|
|
/*
|
|
|
|
* For use during amoptions: get the strlen of a string option
|
|
|
|
* (either default or the user defined value)
|
|
|
|
*/
|
|
|
|
#define GET_STRING_RELOPTION_LEN(option) \
|
|
|
|
((option).isset ? strlen((option).values.string_val) : \
|
|
|
|
((relopt_string *) (option).gen)->default_len)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* For use by code reading options already parsed: get a pointer to the string
|
|
|
|
* value itself. "optstruct" is the StdRdOption struct or equivalent, "member"
|
|
|
|
* is the struct member corresponding to the string option
|
|
|
|
*/
|
|
|
|
#define GET_STRING_RELOPTION(optstruct, member) \
|
|
|
|
((optstruct)->member == 0 ? NULL : \
|
2009-01-12 22:02:15 +01:00
|
|
|
(char *)(optstruct) + (optstruct)->member)
|
2009-01-08 20:34:41 +01:00
|
|
|
|
|
|
|
|
2009-01-05 18:14:28 +01:00
|
|
|
extern int add_reloption_kind(void);
|
|
|
|
extern void add_bool_reloption(int kind, char *name, char *desc,
|
|
|
|
bool default_val);
|
|
|
|
extern void add_int_reloption(int kind, char *name, char *desc,
|
|
|
|
int default_val, int min_val, int max_val);
|
|
|
|
extern void add_real_reloption(int kind, char *name, char *desc,
|
|
|
|
double default_val, double min_val, double max_val);
|
|
|
|
extern void add_string_reloption(int kind, char *name, char *desc,
|
2009-01-08 20:34:41 +01:00
|
|
|
char *default_val, validate_string_relopt validator);
|
2009-01-12 22:02:15 +01:00
|
|
|
|
2006-07-04 00:45:41 +02:00
|
|
|
extern Datum transformRelOptions(Datum oldOptions, List *defList,
|
2006-10-04 02:30:14 +02:00
|
|
|
bool ignoreOids, bool isReset);
|
2007-12-02 00:44:44 +01:00
|
|
|
extern List *untransformRelOptions(Datum options);
|
2009-01-05 18:14:28 +01:00
|
|
|
extern relopt_value *parseRelOptions(Datum options, bool validate,
|
|
|
|
relopt_kind kind, int *numrelopts);
|
2009-01-12 22:02:15 +01:00
|
|
|
extern void *allocateReloptStruct(Size base, relopt_value *options,
|
|
|
|
int numoptions);
|
|
|
|
extern void fillRelOptions(void *rdopts, Size basesize, relopt_value *options,
|
|
|
|
int numoptions, bool validate, relopt_parse_elt *elems,
|
|
|
|
int nelems);
|
2006-07-04 00:45:41 +02:00
|
|
|
|
|
|
|
extern bytea *default_reloptions(Datum reloptions, bool validate,
|
2009-01-05 18:14:28 +01:00
|
|
|
relopt_kind kind);
|
2006-07-04 00:45:41 +02:00
|
|
|
extern bytea *heap_reloptions(char relkind, Datum reloptions, bool validate);
|
|
|
|
extern bytea *index_reloptions(RegProcedure amoptions, Datum reloptions,
|
2009-01-05 18:14:28 +01:00
|
|
|
bool validate);
|
2006-07-04 00:45:41 +02:00
|
|
|
|
|
|
|
#endif /* RELOPTIONS_H */
|