2006-07-04 00:45:41 +02:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* reloptions.h
|
2010-01-05 22:54:00 +01:00
|
|
|
* Core support for relation and tablespace options (pg_class.reloptions
|
|
|
|
* and pg_tablespace.spcoptions)
|
2006-07-04 00:45:41 +02:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*
|
2016-01-02 19:33:40 +01:00
|
|
|
* Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
|
2006-07-04 00:45:41 +02:00
|
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
|
|
*
|
2010-09-20 22:08:53 +02:00
|
|
|
* src/include/access/reloptions.h
|
2006-07-04 00:45:41 +02:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef RELOPTIONS_H
|
|
|
|
#define RELOPTIONS_H
|
|
|
|
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
#include "access/amapi.h"
|
2009-01-26 20:41:06 +01:00
|
|
|
#include "access/htup.h"
|
2012-08-30 22:15:44 +02:00
|
|
|
#include "access/tupdesc.h"
|
2006-07-04 00:45:41 +02:00
|
|
|
#include "nodes/pg_list.h"
|
2015-08-14 15:19:28 +02:00
|
|
|
#include "storage/lock.h"
|
2006-07-04 00:45:41 +02:00
|
|
|
|
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
|
|
|
|
{
|
2009-06-11 16:49:15 +02:00
|
|
|
RELOPT_KIND_HEAP = (1 << 0),
|
|
|
|
RELOPT_KIND_TOAST = (1 << 1),
|
|
|
|
RELOPT_KIND_BTREE = (1 << 2),
|
|
|
|
RELOPT_KIND_HASH = (1 << 3),
|
|
|
|
RELOPT_KIND_GIN = (1 << 4),
|
|
|
|
RELOPT_KIND_GIST = (1 << 5),
|
2010-01-22 17:40:19 +01:00
|
|
|
RELOPT_KIND_ATTRIBUTE = (1 << 6),
|
|
|
|
RELOPT_KIND_TABLESPACE = (1 << 7),
|
2011-12-17 22:41:16 +01:00
|
|
|
RELOPT_KIND_SPGIST = (1 << 8),
|
2011-12-22 22:15:57 +01:00
|
|
|
RELOPT_KIND_VIEW = (1 << 9),
|
BRIN: Block Range Indexes
BRIN is a new index access method intended to accelerate scans of very
large tables, without the maintenance overhead of btrees or other
traditional indexes. They work by maintaining "summary" data about
block ranges. Bitmap index scans work by reading each summary tuple and
comparing them with the query quals; all pages in the range are returned
in a lossy TID bitmap if the quals are consistent with the values in the
summary tuple, otherwise not. Normal index scans are not supported
because these indexes do not store TIDs.
As new tuples are added into the index, the summary information is
updated (if the block range in which the tuple is added is already
summarized) or not; in the latter case, a subsequent pass of VACUUM or
the brin_summarize_new_values() function will create the summary
information.
For data types with natural 1-D sort orders, the summary info consists
of the maximum and the minimum values of each indexed column within each
page range. This type of operator class we call "Minmax", and we
supply a bunch of them for most data types with B-tree opclasses.
Since the BRIN code is generalized, other approaches are possible for
things such as arrays, geometric types, ranges, etc; even for things
such as enum types we could do something different than minmax with
better results. In this commit I only include minmax.
Catalog version bumped due to new builtin catalog entries.
There's more that could be done here, but this is a good step forwards.
Loosely based on ideas from Simon Riggs; code mostly by Álvaro Herrera,
with contribution by Heikki Linnakangas.
Patch reviewed by: Amit Kapila, Heikki Linnakangas, Robert Haas.
Testing help from Jeff Janes, Erik Rijkers, Emanuel Calvo.
PS:
The research leading to these results has received funding from the
European Union's Seventh Framework Programme (FP7/2007-2013) under
grant agreement n° 318633.
2014-11-07 20:38:14 +01:00
|
|
|
RELOPT_KIND_BRIN = (1 << 10),
|
2009-01-05 18:14:28 +01:00
|
|
|
/* if you add a new kind, make sure you update "last_default" too */
|
BRIN: Block Range Indexes
BRIN is a new index access method intended to accelerate scans of very
large tables, without the maintenance overhead of btrees or other
traditional indexes. They work by maintaining "summary" data about
block ranges. Bitmap index scans work by reading each summary tuple and
comparing them with the query quals; all pages in the range are returned
in a lossy TID bitmap if the quals are consistent with the values in the
summary tuple, otherwise not. Normal index scans are not supported
because these indexes do not store TIDs.
As new tuples are added into the index, the summary information is
updated (if the block range in which the tuple is added is already
summarized) or not; in the latter case, a subsequent pass of VACUUM or
the brin_summarize_new_values() function will create the summary
information.
For data types with natural 1-D sort orders, the summary info consists
of the maximum and the minimum values of each indexed column within each
page range. This type of operator class we call "Minmax", and we
supply a bunch of them for most data types with B-tree opclasses.
Since the BRIN code is generalized, other approaches are possible for
things such as arrays, geometric types, ranges, etc; even for things
such as enum types we could do something different than minmax with
better results. In this commit I only include minmax.
Catalog version bumped due to new builtin catalog entries.
There's more that could be done here, but this is a good step forwards.
Loosely based on ideas from Simon Riggs; code mostly by Álvaro Herrera,
with contribution by Heikki Linnakangas.
Patch reviewed by: Amit Kapila, Heikki Linnakangas, Robert Haas.
Testing help from Jeff Janes, Erik Rijkers, Emanuel Calvo.
PS:
The research leading to these results has received funding from the
European Union's Seventh Framework Programme (FP7/2007-2013) under
grant agreement n° 318633.
2014-11-07 20:38:14 +01:00
|
|
|
RELOPT_KIND_LAST_DEFAULT = RELOPT_KIND_BRIN,
|
2009-05-25 00:22:44 +02:00
|
|
|
/* some compilers treat enums as signed ints, so we can't use 1 << 31 */
|
|
|
|
RELOPT_KIND_MAX = (1 << 30)
|
2009-01-05 18:14:28 +01:00
|
|
|
} relopt_kind;
|
|
|
|
|
2009-02-02 20:31:40 +01:00
|
|
|
/* reloption namespaces allowed for heaps -- currently only TOAST */
|
|
|
|
#define HEAP_RELOPT_NAMESPACES { "toast", NULL }
|
|
|
|
|
2009-01-05 18:14:28 +01:00
|
|
|
/* generic struct to hold shared data */
|
|
|
|
typedef struct relopt_gen
|
|
|
|
{
|
2009-06-11 16:49:15 +02:00
|
|
|
const char *name; /* must be first (used as list termination
|
|
|
|
* marker) */
|
2009-01-05 18:14:28 +01:00
|
|
|
const char *desc;
|
2009-04-04 02:45:02 +02:00
|
|
|
bits32 kinds;
|
2015-08-14 15:19:28 +02:00
|
|
|
LOCKMODE lockmode;
|
2009-01-05 18:14:28 +01:00
|
|
|
int namelen;
|
2009-06-11 16:49:15 +02:00
|
|
|
relopt_type type;
|
2009-01-05 18:14:28 +01:00
|
|
|
} relopt_gen;
|
|
|
|
|
|
|
|
/* holds a parsed value */
|
|
|
|
typedef struct relopt_value
|
|
|
|
{
|
|
|
|
relopt_gen *gen;
|
|
|
|
bool isset;
|
|
|
|
union
|
|
|
|
{
|
2009-06-11 16:49:15 +02:00
|
|
|
bool bool_val;
|
|
|
|
int int_val;
|
|
|
|
double real_val;
|
|
|
|
char *string_val; /* allocated separately */
|
|
|
|
} values;
|
2009-01-05 18:14:28 +01:00
|
|
|
} 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-06-11 16:49:15 +02:00
|
|
|
validate_string_relopt validate_cb;
|
2011-08-09 14:25:44 +02:00
|
|
|
char *default_val;
|
2009-01-05 18:14:28 +01:00
|
|
|
} relopt_string;
|
|
|
|
|
2009-03-23 17:36:27 +01:00
|
|
|
/* This is the table datatype for fillRelOptions */
|
2009-01-12 22:02:15 +01:00
|
|
|
typedef struct
|
|
|
|
{
|
2009-03-23 17:36:27 +01:00
|
|
|
const char *optname; /* option's name */
|
2009-06-11 16:49:15 +02:00
|
|
|
relopt_type opttype; /* option's datatype */
|
2009-03-23 17:36:27 +01:00
|
|
|
int offset; /* offset of field in result struct */
|
2009-01-12 22:02:15 +01:00
|
|
|
} 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++)
|
|
|
|
* {
|
2009-06-11 16:49:15 +02:00
|
|
|
* 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")));
|
|
|
|
* }
|
2009-01-12 22:02:15 +01:00
|
|
|
*
|
2009-06-11 16:49:15 +02:00
|
|
|
* 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 option's
|
|
|
|
* code 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) \
|
2009-06-11 16:49:15 +02:00
|
|
|
var = option.values.int_val; \
|
2009-01-12 22:02:15 +01:00
|
|
|
else \
|
2009-06-11 16:49:15 +02:00
|
|
|
var = ((relopt_int *) option.gen)->default_val; \
|
2009-01-12 22:02:15 +01:00
|
|
|
(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) \
|
2009-06-11 16:49:15 +02:00
|
|
|
var = option.values.bool_val; \
|
2009-01-12 22:02:15 +01:00
|
|
|
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-06-11 16:49:15 +02:00
|
|
|
#define HANDLE_REAL_RELOPTION(optname, var, option, wasset) \
|
2009-01-12 22:02:15 +01:00
|
|
|
do { \
|
|
|
|
if (option.isset) \
|
2009-06-11 16:49:15 +02:00
|
|
|
var = option.values.real_val; \
|
2009-01-12 22:02:15 +01:00
|
|
|
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
|
2014-05-06 18:12:18 +02:00
|
|
|
* present, including terminating \0 for every option. SET_VARSIZE() must be
|
2009-01-06 15:47:37 +01:00
|
|
|
* called on the struct with this offset as the second argument, after all the
|
|
|
|
* string options have been processed.
|
|
|
|
*/
|
2009-06-11 16:49:15 +02:00
|
|
|
#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-04-04 02:45:02 +02:00
|
|
|
extern relopt_kind add_reloption_kind(void);
|
|
|
|
extern void add_bool_reloption(bits32 kinds, char *name, char *desc,
|
2009-01-05 18:14:28 +01:00
|
|
|
bool default_val);
|
2009-04-04 02:45:02 +02:00
|
|
|
extern void add_int_reloption(bits32 kinds, char *name, char *desc,
|
2014-08-28 22:10:47 +02:00
|
|
|
int default_val, int min_val, int max_val);
|
2009-04-04 02:45:02 +02:00
|
|
|
extern void add_real_reloption(bits32 kinds, char *name, char *desc,
|
2009-01-05 18:14:28 +01:00
|
|
|
double default_val, double min_val, double max_val);
|
2009-04-04 02:45:02 +02:00
|
|
|
extern void add_string_reloption(bits32 kinds, 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,
|
2009-02-02 20:31:40 +01:00
|
|
|
char *namspace, char *validnsps[],
|
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-26 20:41:06 +01:00
|
|
|
extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
amoptions_function amoptions);
|
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);
|
2009-03-23 17:36:27 +01:00
|
|
|
extern void fillRelOptions(void *rdopts, Size basesize,
|
2009-06-11 16:49:15 +02:00
|
|
|
relopt_value *options, int numoptions,
|
|
|
|
bool validate,
|
|
|
|
const 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);
|
2014-07-14 23:24:40 +02:00
|
|
|
extern bytea *view_reloptions(Datum reloptions, bool validate);
|
Restructure index access method API to hide most of it at the C level.
This patch reduces pg_am to just two columns, a name and a handler
function. All the data formerly obtained from pg_am is now provided
in a C struct returned by the handler function. This is similar to
the designs we've adopted for FDWs and tablesample methods. There
are multiple advantages. For one, the index AM's support functions
are now simple C functions, making them faster to call and much less
error-prone, since the C compiler can now check function signatures.
For another, this will make it far more practical to define index access
methods in installable extensions.
A disadvantage is that SQL-level code can no longer see attributes
of index AMs; in particular, some of the crosschecks in the opr_sanity
regression test are no longer possible from SQL. We've addressed that
by adding a facility for the index AM to perform such checks instead.
(Much more could be done in that line, but for now we're content if the
amvalidate functions more or less replace what opr_sanity used to do.)
We might also want to expose some sort of reporting functionality, but
this patch doesn't do that.
Alexander Korotkov, reviewed by Petr Jelínek, and rather heavily
editorialized on by me.
2016-01-18 01:36:59 +01:00
|
|
|
extern bytea *index_reloptions(amoptions_function amoptions, Datum reloptions,
|
2009-06-11 16:49:15 +02:00
|
|
|
bool validate);
|
2010-01-22 17:40:19 +01:00
|
|
|
extern bytea *attribute_reloptions(Datum reloptions, bool validate);
|
2010-01-05 22:54:00 +01:00
|
|
|
extern bytea *tablespace_reloptions(Datum reloptions, bool validate);
|
2015-08-14 15:19:28 +02:00
|
|
|
extern LOCKMODE AlterTableGetRelOptionsLockLevel(List *defList);
|
2006-07-04 00:45:41 +02:00
|
|
|
|
|
|
|
#endif /* RELOPTIONS_H */
|