mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Allow reloption names to have qualifiers, initially supporting a TOAST
qualifier, and add support for this in pg_dump. This allows TOAST tables to have user-defined fillfactor, and will also enable us to move the autovacuum parameters to reloptions without taking away the possibility of setting values for TOAST tables.
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.69 2008/11/14 10:22:46 petere Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.70 2009/02/02 19:31:38 alvherre Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -231,7 +231,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The name of an index-method-specific storage parameter. See
|
The name of an index-method-specific storage parameter. See
|
||||||
below for details.
|
<xref linkend="sql-createindex-storage-parameters" endterm="sql-createindex-storage-parameters-title">
|
||||||
|
for details.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -265,7 +266,8 @@ CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] <replaceable class="parameter">name</re
|
|||||||
<para>
|
<para>
|
||||||
The <literal>WITH</> clause can specify <firstterm>storage parameters</>
|
The <literal>WITH</> clause can specify <firstterm>storage parameters</>
|
||||||
for indexes. Each index method can have its own set of allowed storage
|
for indexes. Each index method can have its own set of allowed storage
|
||||||
parameters. The built-in index methods all accept a single parameter:
|
parameters. The <literal>B-tree</literal>, <literal>hash</literal> and
|
||||||
|
<literal>GiST</literal> built-in index methods all accept a single parameter:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.111 2008/11/14 10:22:46 petere Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.112 2009/02/02 19:31:38 alvherre Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -690,8 +690,8 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
|||||||
for tables, and for indexes associated with a <literal>UNIQUE</literal> or
|
for tables, and for indexes associated with a <literal>UNIQUE</literal> or
|
||||||
<literal>PRIMARY KEY</literal> constraint. Storage parameters for
|
<literal>PRIMARY KEY</literal> constraint. Storage parameters for
|
||||||
indexes are documented in <xref linkend="SQL-CREATEINDEX"
|
indexes are documented in <xref linkend="SQL-CREATEINDEX"
|
||||||
endterm="sql-createindex-title">. The only storage parameter currently
|
endterm="sql-createindex-title">. The storage parameters currently
|
||||||
available for tables is:
|
available for tables are:
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
@ -714,6 +714,16 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><literal>TOAST.FILLFACTOR</literal></term>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Same as above, for the supplementary storage table, if any; see
|
||||||
|
<xref linkend="storage-toast">.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.19 2009/01/26 19:41:06 alvherre Exp $
|
* $PostgreSQL: pgsql/src/backend/access/common/reloptions.c,v 1.20 2009/02/02 19:31:38 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -390,8 +390,10 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transform a relation options list (list of DefElem) into the text array
|
* Transform a relation options list (list of ReloptElem) into the text array
|
||||||
* format that is kept in pg_class.reloptions.
|
* format that is kept in pg_class.reloptions, including only those options
|
||||||
|
* that are in the passed namespace. The output values do not include the
|
||||||
|
* namespace.
|
||||||
*
|
*
|
||||||
* This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and
|
* This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and
|
||||||
* ALTER TABLE RESET. In the ALTER cases, oldOptions is the existing
|
* ALTER TABLE RESET. In the ALTER cases, oldOptions is the existing
|
||||||
@ -402,14 +404,17 @@ add_string_reloption(int kind, char *name, char *desc, char *default_val,
|
|||||||
* in the list (it will be or has been handled by interpretOidsOption()).
|
* in the list (it will be or has been handled by interpretOidsOption()).
|
||||||
*
|
*
|
||||||
* Note that this is not responsible for determining whether the options
|
* Note that this is not responsible for determining whether the options
|
||||||
* are valid.
|
* are valid, but it does check that namespaces for all the options given are
|
||||||
|
* listed in validnsps. The NULL namespace is always valid and needs not be
|
||||||
|
* explicitely listed. Passing a NULL pointer means that only the NULL
|
||||||
|
* namespace is valid.
|
||||||
*
|
*
|
||||||
* Both oldOptions and the result are text arrays (or NULL for "default"),
|
* Both oldOptions and the result are text arrays (or NULL for "default"),
|
||||||
* but we declare them as Datums to avoid including array.h in reloptions.h.
|
* but we declare them as Datums to avoid including array.h in reloptions.h.
|
||||||
*/
|
*/
|
||||||
Datum
|
Datum
|
||||||
transformRelOptions(Datum oldOptions, List *defList,
|
transformRelOptions(Datum oldOptions, List *defList, char *namspace,
|
||||||
bool ignoreOids, bool isReset)
|
char *validnsps[], bool ignoreOids, bool isReset)
|
||||||
{
|
{
|
||||||
Datum result;
|
Datum result;
|
||||||
ArrayBuildState *astate;
|
ArrayBuildState *astate;
|
||||||
@ -444,11 +449,23 @@ transformRelOptions(Datum oldOptions, List *defList,
|
|||||||
/* Search for a match in defList */
|
/* Search for a match in defList */
|
||||||
foreach(cell, defList)
|
foreach(cell, defList)
|
||||||
{
|
{
|
||||||
DefElem *def = lfirst(cell);
|
ReloptElem *def = lfirst(cell);
|
||||||
int kw_len = strlen(def->defname);
|
int kw_len;
|
||||||
|
|
||||||
|
/* ignore if not in the same namespace */
|
||||||
|
if (namspace == NULL)
|
||||||
|
{
|
||||||
|
if (def->nmspc != NULL)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (def->nmspc == NULL)
|
||||||
|
continue;
|
||||||
|
else if (pg_strcasecmp(def->nmspc, namspace) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
kw_len = strlen(def->optname);
|
||||||
if (text_len > kw_len && text_str[kw_len] == '=' &&
|
if (text_len > kw_len && text_str[kw_len] == '=' &&
|
||||||
pg_strncasecmp(text_str, def->defname, kw_len) == 0)
|
pg_strncasecmp(text_str, def->optname, kw_len) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!cell)
|
if (!cell)
|
||||||
@ -468,7 +485,8 @@ transformRelOptions(Datum oldOptions, List *defList,
|
|||||||
*/
|
*/
|
||||||
foreach(cell, defList)
|
foreach(cell, defList)
|
||||||
{
|
{
|
||||||
DefElem *def = lfirst(cell);
|
ReloptElem *def = lfirst(cell);
|
||||||
|
|
||||||
|
|
||||||
if (isReset)
|
if (isReset)
|
||||||
{
|
{
|
||||||
@ -483,22 +501,62 @@ transformRelOptions(Datum oldOptions, List *defList,
|
|||||||
const char *value;
|
const char *value;
|
||||||
Size len;
|
Size len;
|
||||||
|
|
||||||
if (ignoreOids && pg_strcasecmp(def->defname, "oids") == 0)
|
/*
|
||||||
|
* Error out if the namespace is not valid. A NULL namespace
|
||||||
|
* is always valid.
|
||||||
|
*/
|
||||||
|
if (def->nmspc != NULL)
|
||||||
|
{
|
||||||
|
bool valid = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (validnsps)
|
||||||
|
{
|
||||||
|
for (i = 0; validnsps[i]; i++)
|
||||||
|
{
|
||||||
|
if (pg_strcasecmp(def->nmspc, validnsps[i]) == 0)
|
||||||
|
{
|
||||||
|
valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||||
|
errmsg("unrecognized parameter namespace \"%s\"",
|
||||||
|
def->nmspc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignoreOids && pg_strcasecmp(def->optname, "oids") == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* ignore if not in the same namespace */
|
||||||
|
if (namspace == NULL)
|
||||||
|
{
|
||||||
|
if (def->nmspc != NULL)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (def->nmspc == NULL)
|
||||||
|
continue;
|
||||||
|
else if (pg_strcasecmp(def->nmspc, namspace) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flatten the DefElem into a text string like "name=arg". If we
|
* Flatten the ReloptElem into a text string like "name=arg". If we
|
||||||
* have just "name", assume "name=true" is meant.
|
* have just "name", assume "name=true" is meant. Note: the
|
||||||
|
* namespace is not output.
|
||||||
*/
|
*/
|
||||||
if (def->arg != NULL)
|
if (def->arg != NULL)
|
||||||
value = defGetString(def);
|
value = reloptGetString(def);
|
||||||
else
|
else
|
||||||
value = "true";
|
value = "true";
|
||||||
len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
|
len = VARHDRSZ + strlen(def->optname) + 1 + strlen(value);
|
||||||
/* +1 leaves room for sprintf's trailing null */
|
/* +1 leaves room for sprintf's trailing null */
|
||||||
t = (text *) palloc(len + 1);
|
t = (text *) palloc(len + 1);
|
||||||
SET_VARSIZE(t, len);
|
SET_VARSIZE(t, len);
|
||||||
sprintf(VARDATA(t), "%s=%s", def->defname, value);
|
sprintf(VARDATA(t), "%s=%s", def->optname, value);
|
||||||
|
|
||||||
astate = accumArrayResult(astate, PointerGetDatum(t),
|
astate = accumArrayResult(astate, PointerGetDatum(t),
|
||||||
false, TEXTOID,
|
false, TEXTOID,
|
||||||
@ -944,7 +1002,7 @@ default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse options for heaps (and perhaps someday toast tables).
|
* Parse options for heaps and toast tables.
|
||||||
*/
|
*/
|
||||||
bytea *
|
bytea *
|
||||||
heap_reloptions(char relkind, Datum reloptions, bool validate)
|
heap_reloptions(char relkind, Datum reloptions, bool validate)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.12 2009/01/01 17:23:37 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/catalog/toasting.c,v 1.13 2009/02/02 19:31:38 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -32,7 +32,8 @@
|
|||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid);
|
static bool create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
|
||||||
|
Datum reloptions);
|
||||||
static bool needs_toast_table(Relation rel);
|
static bool needs_toast_table(Relation rel);
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ static bool needs_toast_table(Relation rel);
|
|||||||
* to end with CommandCounterIncrement if it makes any changes.
|
* to end with CommandCounterIncrement if it makes any changes.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
AlterTableCreateToastTable(Oid relOid)
|
AlterTableCreateToastTable(Oid relOid, Datum reloptions)
|
||||||
{
|
{
|
||||||
Relation rel;
|
Relation rel;
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ AlterTableCreateToastTable(Oid relOid)
|
|||||||
rel = heap_open(relOid, AccessExclusiveLock);
|
rel = heap_open(relOid, AccessExclusiveLock);
|
||||||
|
|
||||||
/* create_toast_table does all the work */
|
/* create_toast_table does all the work */
|
||||||
(void) create_toast_table(rel, InvalidOid, InvalidOid);
|
(void) create_toast_table(rel, InvalidOid, InvalidOid, reloptions);
|
||||||
|
|
||||||
heap_close(rel, NoLock);
|
heap_close(rel, NoLock);
|
||||||
}
|
}
|
||||||
@ -84,7 +85,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
|
|||||||
relName)));
|
relName)));
|
||||||
|
|
||||||
/* create_toast_table does all the work */
|
/* create_toast_table does all the work */
|
||||||
if (!create_toast_table(rel, toastOid, toastIndexOid))
|
if (!create_toast_table(rel, toastOid, toastIndexOid, (Datum) 0))
|
||||||
elog(ERROR, "\"%s\" does not require a toast table",
|
elog(ERROR, "\"%s\" does not require a toast table",
|
||||||
relName);
|
relName);
|
||||||
|
|
||||||
@ -100,7 +101,7 @@ BootstrapToastTable(char *relName, Oid toastOid, Oid toastIndexOid)
|
|||||||
* bootstrap they can be nonzero to specify hand-assigned OIDs
|
* bootstrap they can be nonzero to specify hand-assigned OIDs
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
|
create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid, Datum reloptions)
|
||||||
{
|
{
|
||||||
Oid relOid = RelationGetRelid(rel);
|
Oid relOid = RelationGetRelid(rel);
|
||||||
HeapTuple reltup;
|
HeapTuple reltup;
|
||||||
@ -183,10 +184,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
|
|||||||
else
|
else
|
||||||
namespaceid = PG_TOAST_NAMESPACE;
|
namespaceid = PG_TOAST_NAMESPACE;
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX would it make sense to apply the master's reloptions to the toast
|
|
||||||
* table? Or maybe some toast-specific reloptions?
|
|
||||||
*/
|
|
||||||
toast_relid = heap_create_with_catalog(toast_relname,
|
toast_relid = heap_create_with_catalog(toast_relname,
|
||||||
namespaceid,
|
namespaceid,
|
||||||
rel->rd_rel->reltablespace,
|
rel->rd_rel->reltablespace,
|
||||||
@ -199,7 +196,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid)
|
|||||||
true,
|
true,
|
||||||
0,
|
0,
|
||||||
ONCOMMIT_NOOP,
|
ONCOMMIT_NOOP,
|
||||||
(Datum) 0,
|
reloptions,
|
||||||
true);
|
true);
|
||||||
|
|
||||||
/* make the toast relation visible, else index creation will fail */
|
/* make the toast relation visible, else index creation will fail */
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.181 2009/01/16 13:27:23 heikki Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.182 2009/02/02 19:31:38 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -668,6 +668,7 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
|
|||||||
TupleDesc OldHeapDesc,
|
TupleDesc OldHeapDesc,
|
||||||
tupdesc;
|
tupdesc;
|
||||||
Oid OIDNewHeap;
|
Oid OIDNewHeap;
|
||||||
|
Oid toastid;
|
||||||
Relation OldHeap;
|
Relation OldHeap;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Datum reloptions;
|
Datum reloptions;
|
||||||
@ -726,7 +727,24 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
|
|||||||
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
|
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
|
||||||
* the TOAST table will be visible for insertion.
|
* the TOAST table will be visible for insertion.
|
||||||
*/
|
*/
|
||||||
AlterTableCreateToastTable(OIDNewHeap);
|
toastid = OldHeap->rd_rel->reltoastrelid;
|
||||||
|
reloptions = (Datum) 0;
|
||||||
|
if (OidIsValid(toastid))
|
||||||
|
{
|
||||||
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(toastid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "cache lookup failed for relation %u", toastid);
|
||||||
|
reloptions = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions,
|
||||||
|
&isNull);
|
||||||
|
if (isNull)
|
||||||
|
reloptions = (Datum) 0;
|
||||||
|
}
|
||||||
|
AlterTableCreateToastTable(OIDNewHeap, reloptions);
|
||||||
|
|
||||||
|
if (OidIsValid(toastid))
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
heap_close(OldHeap, NoLock);
|
heap_close(OldHeap, NoLock);
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.102 2009/01/01 17:23:37 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.103 2009/02/02 19:31:38 alvherre Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
@ -55,24 +55,20 @@ case_translate_language_name(const char *input)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
static char *
|
||||||
* Extract a string value (otherwise uninterpreted) from a DefElem.
|
nodeGetString(Node *value, char *name)
|
||||||
*/
|
|
||||||
char *
|
|
||||||
defGetString(DefElem *def)
|
|
||||||
{
|
{
|
||||||
if (def->arg == NULL)
|
if (value == NULL)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("%s requires a parameter",
|
errmsg("%s requires a parameter", name)));
|
||||||
def->defname)));
|
switch (nodeTag(value))
|
||||||
switch (nodeTag(def->arg))
|
|
||||||
{
|
{
|
||||||
case T_Integer:
|
case T_Integer:
|
||||||
{
|
{
|
||||||
char *str = palloc(32);
|
char *str = palloc(32);
|
||||||
|
|
||||||
snprintf(str, 32, "%ld", (long) intVal(def->arg));
|
snprintf(str, 32, "%ld", (long) intVal(value));
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
case T_Float:
|
case T_Float:
|
||||||
@ -81,19 +77,28 @@ defGetString(DefElem *def)
|
|||||||
* T_Float values are kept in string form, so this type cheat
|
* T_Float values are kept in string form, so this type cheat
|
||||||
* works (and doesn't risk losing precision)
|
* works (and doesn't risk losing precision)
|
||||||
*/
|
*/
|
||||||
return strVal(def->arg);
|
return strVal(value);
|
||||||
case T_String:
|
case T_String:
|
||||||
return strVal(def->arg);
|
return strVal(value);
|
||||||
case T_TypeName:
|
case T_TypeName:
|
||||||
return TypeNameToString((TypeName *) def->arg);
|
return TypeNameToString((TypeName *) value);
|
||||||
case T_List:
|
case T_List:
|
||||||
return NameListToString((List *) def->arg);
|
return NameListToString((List *) value);
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(def->arg));
|
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(value));
|
||||||
}
|
}
|
||||||
return NULL; /* keep compiler quiet */
|
return NULL; /* keep compiler quiet */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract a string value (otherwise uninterpreted) from a DefElem.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
defGetString(DefElem *def)
|
||||||
|
{
|
||||||
|
return nodeGetString(def->arg, def->defname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extract a numeric value (actually double) from a DefElem.
|
* Extract a numeric value (actually double) from a DefElem.
|
||||||
*/
|
*/
|
||||||
@ -120,25 +125,22 @@ defGetNumeric(DefElem *def)
|
|||||||
return 0; /* keep compiler quiet */
|
return 0; /* keep compiler quiet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static bool
|
||||||
* Extract a boolean value from a DefElem.
|
nodeGetBoolean(Node *value, char *name)
|
||||||
*/
|
|
||||||
bool
|
|
||||||
defGetBoolean(DefElem *def)
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If no parameter given, assume "true" is meant.
|
* If no parameter given, assume "true" is meant.
|
||||||
*/
|
*/
|
||||||
if (def->arg == NULL)
|
if (value == NULL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow 0, 1, "true", "false"
|
* Allow 0, 1, "true", "false"
|
||||||
*/
|
*/
|
||||||
switch (nodeTag(def->arg))
|
switch (nodeTag(value))
|
||||||
{
|
{
|
||||||
case T_Integer:
|
case T_Integer:
|
||||||
switch (intVal(def->arg))
|
switch (intVal(value))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return false;
|
return false;
|
||||||
@ -151,7 +153,7 @@ defGetBoolean(DefElem *def)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
char *sval = defGetString(def);
|
char *sval = nodeGetString(value, name);
|
||||||
|
|
||||||
if (pg_strcasecmp(sval, "true") == 0)
|
if (pg_strcasecmp(sval, "true") == 0)
|
||||||
return true;
|
return true;
|
||||||
@ -163,11 +165,19 @@ defGetBoolean(DefElem *def)
|
|||||||
}
|
}
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||||
errmsg("%s requires a Boolean value",
|
errmsg("%s requires a Boolean value", name)));
|
||||||
def->defname)));
|
|
||||||
return false; /* keep compiler quiet */
|
return false; /* keep compiler quiet */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract a boolean value from a DefElem.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
defGetBoolean(DefElem *def)
|
||||||
|
{
|
||||||
|
return nodeGetBoolean(def->arg, def->defname);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extract an int64 value from a DefElem.
|
* Extract an int64 value from a DefElem.
|
||||||
*/
|
*/
|
||||||
@ -305,15 +315,35 @@ defGetTypeLength(DefElem *def)
|
|||||||
return 0; /* keep compiler quiet */
|
return 0; /* keep compiler quiet */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a DefElem setting "oids" to the specified value.
|
|
||||||
*/
|
|
||||||
DefElem *
|
|
||||||
defWithOids(bool value)
|
|
||||||
{
|
|
||||||
DefElem *f = makeNode(DefElem);
|
|
||||||
|
|
||||||
f->defname = "oids";
|
/*
|
||||||
|
* Extract a string value (otherwise uninterpreted) from a ReloptElem.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
reloptGetString(ReloptElem *relopt)
|
||||||
|
{
|
||||||
|
return nodeGetString(relopt->arg, relopt->optname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract a boolean value from a ReloptElem.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
reloptGetBoolean(ReloptElem *relopt)
|
||||||
|
{
|
||||||
|
return nodeGetBoolean(relopt->arg, relopt->optname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a ReloptElem setting "oids" to the specified value.
|
||||||
|
*/
|
||||||
|
ReloptElem *
|
||||||
|
reloptWithOids(bool value)
|
||||||
|
{
|
||||||
|
ReloptElem *f = makeNode(ReloptElem);
|
||||||
|
|
||||||
|
f->optname = "oids";
|
||||||
|
f->nmspc = NULL;
|
||||||
f->arg = (Node *) makeInteger(value);
|
f->arg = (Node *) makeInteger(value);
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.181 2009/01/01 17:23:38 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.182 2009/02/02 19:31:38 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -398,7 +398,7 @@ DefineIndex(RangeVar *heapRelation,
|
|||||||
/*
|
/*
|
||||||
* Parse AM-specific options, convert to text array form, validate.
|
* Parse AM-specific options, convert to text array form, validate.
|
||||||
*/
|
*/
|
||||||
reloptions = transformRelOptions((Datum) 0, options, false, false);
|
reloptions = transformRelOptions((Datum) 0, options, NULL, NULL, false, false);
|
||||||
|
|
||||||
(void) index_reloptions(amoptions, reloptions, true);
|
(void) index_reloptions(amoptions, reloptions, true);
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.157 2009/01/20 18:59:37 heikki Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.158 2009/02/02 19:31:38 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -198,7 +198,7 @@ DefineSequence(CreateSeqStmt *seq)
|
|||||||
stmt->relation = seq->sequence;
|
stmt->relation = seq->sequence;
|
||||||
stmt->inhRelations = NIL;
|
stmt->inhRelations = NIL;
|
||||||
stmt->constraints = NIL;
|
stmt->constraints = NIL;
|
||||||
stmt->options = list_make1(defWithOids(false));
|
stmt->options = list_make1(reloptWithOids(false));
|
||||||
stmt->oncommit = ONCOMMIT_NOOP;
|
stmt->oncommit = ONCOMMIT_NOOP;
|
||||||
stmt->tablespacename = NULL;
|
stmt->tablespacename = NULL;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.278 2009/01/22 20:16:02 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.279 2009/02/02 19:31:38 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -351,6 +351,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||||||
Datum reloptions;
|
Datum reloptions;
|
||||||
ListCell *listptr;
|
ListCell *listptr;
|
||||||
AttrNumber attnum;
|
AttrNumber attnum;
|
||||||
|
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Truncate relname to appropriate length (probably a waste of time, as
|
* Truncate relname to appropriate length (probably a waste of time, as
|
||||||
@ -418,7 +419,8 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
|||||||
/*
|
/*
|
||||||
* Parse and validate reloptions, if any.
|
* Parse and validate reloptions, if any.
|
||||||
*/
|
*/
|
||||||
reloptions = transformRelOptions((Datum) 0, stmt->options, true, false);
|
reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
|
||||||
|
true, false);
|
||||||
|
|
||||||
(void) heap_reloptions(relkind, reloptions, true);
|
(void) heap_reloptions(relkind, reloptions, true);
|
||||||
|
|
||||||
@ -2572,7 +2574,7 @@ ATRewriteCatalogs(List **wqueue)
|
|||||||
(tab->subcmds[AT_PASS_ADD_COL] ||
|
(tab->subcmds[AT_PASS_ADD_COL] ||
|
||||||
tab->subcmds[AT_PASS_ALTER_TYPE] ||
|
tab->subcmds[AT_PASS_ALTER_TYPE] ||
|
||||||
tab->subcmds[AT_PASS_COL_ATTRS]))
|
tab->subcmds[AT_PASS_COL_ATTRS]))
|
||||||
AlterTableCreateToastTable(tab->relid);
|
AlterTableCreateToastTable(tab->relid, (Datum) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6457,6 +6459,7 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
|
|||||||
Datum repl_val[Natts_pg_class];
|
Datum repl_val[Natts_pg_class];
|
||||||
bool repl_null[Natts_pg_class];
|
bool repl_null[Natts_pg_class];
|
||||||
bool repl_repl[Natts_pg_class];
|
bool repl_repl[Natts_pg_class];
|
||||||
|
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
|
||||||
|
|
||||||
if (defList == NIL)
|
if (defList == NIL)
|
||||||
return; /* nothing to do */
|
return; /* nothing to do */
|
||||||
@ -6475,7 +6478,7 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
|
|||||||
|
|
||||||
/* Generate new proposed reloptions (text array) */
|
/* Generate new proposed reloptions (text array) */
|
||||||
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
|
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
|
||||||
defList, false, isReset);
|
defList, NULL, validnsps, false, isReset);
|
||||||
|
|
||||||
/* Validate */
|
/* Validate */
|
||||||
switch (rel->rd_rel->relkind)
|
switch (rel->rd_rel->relkind)
|
||||||
@ -6521,6 +6524,53 @@ ATExecSetRelOptions(Relation rel, List *defList, bool isReset)
|
|||||||
|
|
||||||
ReleaseSysCache(tuple);
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
/* repeat the whole exercise for the toast table, if there's one */
|
||||||
|
if (OidIsValid(rel->rd_rel->reltoastrelid))
|
||||||
|
{
|
||||||
|
Relation toastrel;
|
||||||
|
Oid toastid = rel->rd_rel->reltoastrelid;
|
||||||
|
|
||||||
|
toastrel = heap_open(toastid, AccessExclusiveLock);
|
||||||
|
|
||||||
|
/* Get the old reloptions */
|
||||||
|
tuple = SearchSysCache(RELOID,
|
||||||
|
ObjectIdGetDatum(toastid),
|
||||||
|
0, 0, 0);
|
||||||
|
if (!HeapTupleIsValid(tuple))
|
||||||
|
elog(ERROR, "cache lookup failed for relation %u", toastid);
|
||||||
|
|
||||||
|
datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
|
||||||
|
|
||||||
|
newOptions = transformRelOptions(isnull ? (Datum) 0 : datum,
|
||||||
|
defList, "toast", validnsps, false, isReset);
|
||||||
|
|
||||||
|
(void) heap_reloptions(RELKIND_TOASTVALUE, newOptions, true);
|
||||||
|
|
||||||
|
memset(repl_val, 0, sizeof(repl_val));
|
||||||
|
memset(repl_null, false, sizeof(repl_null));
|
||||||
|
memset(repl_repl, false, sizeof(repl_repl));
|
||||||
|
|
||||||
|
if (newOptions != (Datum) 0)
|
||||||
|
repl_val[Anum_pg_class_reloptions - 1] = newOptions;
|
||||||
|
else
|
||||||
|
repl_null[Anum_pg_class_reloptions - 1] = true;
|
||||||
|
|
||||||
|
repl_repl[Anum_pg_class_reloptions - 1] = true;
|
||||||
|
|
||||||
|
newtuple = heap_modify_tuple(tuple, RelationGetDescr(pgclass),
|
||||||
|
repl_val, repl_null, repl_repl);
|
||||||
|
|
||||||
|
simple_heap_update(pgclass, &newtuple->t_self, newtuple);
|
||||||
|
|
||||||
|
CatalogUpdateIndexes(pgclass, newtuple);
|
||||||
|
|
||||||
|
heap_freetuple(newtuple);
|
||||||
|
|
||||||
|
ReleaseSysCache(tuple);
|
||||||
|
|
||||||
|
heap_close(toastrel, NoLock);
|
||||||
|
}
|
||||||
|
|
||||||
heap_close(pgclass, RowExclusiveLock);
|
heap_close(pgclass, RowExclusiveLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.130 2009/01/09 15:46:10 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.131 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
* DESCRIPTION
|
* DESCRIPTION
|
||||||
* The "DefineFoo" routines take the parse tree and pick out the
|
* The "DefineFoo" routines take the parse tree and pick out the
|
||||||
@ -1491,7 +1491,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
|
|||||||
createStmt->tableElts = coldeflist;
|
createStmt->tableElts = coldeflist;
|
||||||
createStmt->inhRelations = NIL;
|
createStmt->inhRelations = NIL;
|
||||||
createStmt->constraints = NIL;
|
createStmt->constraints = NIL;
|
||||||
createStmt->options = list_make1(defWithOids(false));
|
createStmt->options = list_make1(reloptWithOids(false));
|
||||||
createStmt->oncommit = ONCOMMIT_NOOP;
|
createStmt->oncommit = ONCOMMIT_NOOP;
|
||||||
createStmt->tablespacename = NULL;
|
createStmt->tablespacename = NULL;
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.113 2009/01/27 12:40:15 petere Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.114 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -229,7 +229,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
|
|||||||
createStmt->tableElts = attrList;
|
createStmt->tableElts = attrList;
|
||||||
createStmt->inhRelations = NIL;
|
createStmt->inhRelations = NIL;
|
||||||
createStmt->constraints = NIL;
|
createStmt->constraints = NIL;
|
||||||
createStmt->options = list_make1(defWithOids(false));
|
createStmt->options = list_make1(reloptWithOids(false));
|
||||||
createStmt->oncommit = ONCOMMIT_NOOP;
|
createStmt->oncommit = ONCOMMIT_NOOP;
|
||||||
createStmt->tablespacename = NULL;
|
createStmt->tablespacename = NULL;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.321 2009/01/22 20:16:03 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.322 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2832,6 +2832,7 @@ OpenIntoRel(QueryDesc *queryDesc)
|
|||||||
Oid intoRelationId;
|
Oid intoRelationId;
|
||||||
TupleDesc tupdesc;
|
TupleDesc tupdesc;
|
||||||
DR_intorel *myState;
|
DR_intorel *myState;
|
||||||
|
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
|
||||||
|
|
||||||
Assert(into);
|
Assert(into);
|
||||||
|
|
||||||
@ -2890,6 +2891,8 @@ OpenIntoRel(QueryDesc *queryDesc)
|
|||||||
/* Parse and validate any reloptions */
|
/* Parse and validate any reloptions */
|
||||||
reloptions = transformRelOptions((Datum) 0,
|
reloptions = transformRelOptions((Datum) 0,
|
||||||
into->options,
|
into->options,
|
||||||
|
NULL,
|
||||||
|
validnsps,
|
||||||
true,
|
true,
|
||||||
false);
|
false);
|
||||||
(void) heap_reloptions(RELKIND_RELATION, reloptions, true);
|
(void) heap_reloptions(RELKIND_RELATION, reloptions, true);
|
||||||
@ -2926,7 +2929,16 @@ OpenIntoRel(QueryDesc *queryDesc)
|
|||||||
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
|
* AlterTableCreateToastTable ends with CommandCounterIncrement(), so that
|
||||||
* the TOAST table will be visible for insertion.
|
* the TOAST table will be visible for insertion.
|
||||||
*/
|
*/
|
||||||
AlterTableCreateToastTable(intoRelationId);
|
reloptions = transformRelOptions((Datum) 0,
|
||||||
|
into->options,
|
||||||
|
"toast",
|
||||||
|
validnsps,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
|
||||||
|
(void) heap_reloptions(RELKIND_TOASTVALUE, reloptions, true);
|
||||||
|
|
||||||
|
AlterTableCreateToastTable(intoRelationId, reloptions);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* And open the constructed table for writing.
|
* And open the constructed table for writing.
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.421 2009/01/22 20:16:03 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.422 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2125,6 +2125,18 @@ _copyOptionDefElem(OptionDefElem *from)
|
|||||||
return newnode;
|
return newnode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ReloptElem *
|
||||||
|
_copyReloptElem(ReloptElem *from)
|
||||||
|
{
|
||||||
|
ReloptElem *newnode = makeNode(ReloptElem);
|
||||||
|
|
||||||
|
COPY_STRING_FIELD(optname);
|
||||||
|
COPY_STRING_FIELD(nmspc);
|
||||||
|
COPY_NODE_FIELD(arg);
|
||||||
|
|
||||||
|
return newnode;
|
||||||
|
}
|
||||||
|
|
||||||
static LockingClause *
|
static LockingClause *
|
||||||
_copyLockingClause(LockingClause *from)
|
_copyLockingClause(LockingClause *from)
|
||||||
{
|
{
|
||||||
@ -4079,6 +4091,9 @@ copyObject(void *from)
|
|||||||
case T_OptionDefElem:
|
case T_OptionDefElem:
|
||||||
retval = _copyOptionDefElem(from);
|
retval = _copyOptionDefElem(from);
|
||||||
break;
|
break;
|
||||||
|
case T_ReloptElem:
|
||||||
|
retval = _copyReloptElem(from);
|
||||||
|
break;
|
||||||
case T_LockingClause:
|
case T_LockingClause:
|
||||||
retval = _copyLockingClause(from);
|
retval = _copyLockingClause(from);
|
||||||
break;
|
break;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.346 2009/01/22 20:16:03 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.347 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -2098,6 +2098,16 @@ _equalOptionDefElem(OptionDefElem *a, OptionDefElem *b)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_equalReloptElem(ReloptElem *a, ReloptElem *b)
|
||||||
|
{
|
||||||
|
COMPARE_STRING_FIELD(nmspc);
|
||||||
|
COMPARE_STRING_FIELD(optname);
|
||||||
|
COMPARE_NODE_FIELD(arg);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_equalLockingClause(LockingClause *a, LockingClause *b)
|
_equalLockingClause(LockingClause *a, LockingClause *b)
|
||||||
{
|
{
|
||||||
@ -2855,6 +2865,9 @@ equal(void *a, void *b)
|
|||||||
case T_OptionDefElem:
|
case T_OptionDefElem:
|
||||||
retval = _equalOptionDefElem(a, b);
|
retval = _equalOptionDefElem(a, b);
|
||||||
break;
|
break;
|
||||||
|
case T_ReloptElem:
|
||||||
|
retval = _equalReloptElem(a, b);
|
||||||
|
break;
|
||||||
case T_LockingClause:
|
case T_LockingClause:
|
||||||
retval = _equalLockingClause(a, b);
|
retval = _equalLockingClause(a, b);
|
||||||
break;
|
break;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.62 2009/01/01 17:23:43 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/makefuncs.c,v 1.63 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -374,3 +374,14 @@ makeOptionDefElem(int op, DefElem *def)
|
|||||||
res->def = def;
|
res->def = def;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReloptElem *
|
||||||
|
makeReloptElem(char *name, char *nmspc, Node *arg)
|
||||||
|
{
|
||||||
|
ReloptElem *res = makeNode(ReloptElem);
|
||||||
|
|
||||||
|
res->optname = name;
|
||||||
|
res->nmspc = nmspc;
|
||||||
|
res->arg = arg;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.350 2009/01/22 20:16:04 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.351 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -1804,6 +1804,16 @@ _outDefElem(StringInfo str, DefElem *node)
|
|||||||
WRITE_NODE_FIELD(arg);
|
WRITE_NODE_FIELD(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_outReloptElem(StringInfo str, ReloptElem *node)
|
||||||
|
{
|
||||||
|
WRITE_NODE_TYPE("RELOPTELEM");
|
||||||
|
|
||||||
|
WRITE_STRING_FIELD(nmspc);
|
||||||
|
WRITE_STRING_FIELD(optname);
|
||||||
|
WRITE_NODE_FIELD(arg);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_outLockingClause(StringInfo str, LockingClause *node)
|
_outLockingClause(StringInfo str, LockingClause *node)
|
||||||
{
|
{
|
||||||
@ -2770,6 +2780,9 @@ _outNode(StringInfo str, void *obj)
|
|||||||
case T_DefElem:
|
case T_DefElem:
|
||||||
_outDefElem(str, obj);
|
_outDefElem(str, obj);
|
||||||
break;
|
break;
|
||||||
|
case T_ReloptElem:
|
||||||
|
_outReloptElem(str, obj);
|
||||||
|
break;
|
||||||
case T_LockingClause:
|
case T_LockingClause:
|
||||||
_outLockingClause(str, obj);
|
_outLockingClause(str, obj);
|
||||||
break;
|
break;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.656 2009/01/22 20:16:05 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.657 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
* HISTORY
|
* HISTORY
|
||||||
* AUTHOR DATE MAJOR EVENT
|
* AUTHOR DATE MAJOR EVENT
|
||||||
@ -164,6 +164,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
FuncWithArgs *funwithargs;
|
FuncWithArgs *funwithargs;
|
||||||
DefElem *defelt;
|
DefElem *defelt;
|
||||||
OptionDefElem *optdef;
|
OptionDefElem *optdef;
|
||||||
|
ReloptElem *reloptel;
|
||||||
SortBy *sortby;
|
SortBy *sortby;
|
||||||
WindowDef *windef;
|
WindowDef *windef;
|
||||||
JoinExpr *jexpr;
|
JoinExpr *jexpr;
|
||||||
@ -271,6 +272,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
|
|
||||||
%type <list> stmtblock stmtmulti
|
%type <list> stmtblock stmtmulti
|
||||||
OptTableElementList TableElementList OptInherit definition
|
OptTableElementList TableElementList OptInherit definition
|
||||||
|
reloptions opt_reloptions
|
||||||
OptWith opt_distinct opt_definition func_args func_args_list
|
OptWith opt_distinct opt_definition func_args func_args_list
|
||||||
func_args_with_defaults func_args_with_defaults_list
|
func_args_with_defaults func_args_with_defaults_list
|
||||||
func_as createfunc_opt_list alterfunc_opt_list
|
func_as createfunc_opt_list alterfunc_opt_list
|
||||||
@ -284,7 +286,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
target_list insert_column_list set_target_list
|
target_list insert_column_list set_target_list
|
||||||
set_clause_list set_clause multiple_set_clause
|
set_clause_list set_clause multiple_set_clause
|
||||||
ctext_expr_list ctext_row def_list indirection opt_indirection
|
ctext_expr_list ctext_row def_list indirection opt_indirection
|
||||||
group_clause TriggerFuncArgs select_limit
|
reloption_list group_clause TriggerFuncArgs select_limit
|
||||||
opt_select_limit opclass_item_list opclass_drop_list
|
opt_select_limit opclass_item_list opclass_drop_list
|
||||||
opt_opfamily transaction_mode_list_or_empty
|
opt_opfamily transaction_mode_list_or_empty
|
||||||
TableFuncElementList opt_type_modifiers
|
TableFuncElementList opt_type_modifiers
|
||||||
@ -342,6 +344,7 @@ static TypeName *TableFuncTypeName(List *columns);
|
|||||||
%type <node> TableElement ConstraintElem TableFuncElement
|
%type <node> TableElement ConstraintElem TableFuncElement
|
||||||
%type <node> columnDef
|
%type <node> columnDef
|
||||||
%type <defelt> def_elem old_aggr_elem
|
%type <defelt> def_elem old_aggr_elem
|
||||||
|
%type <reloptel> reloption_elem
|
||||||
%type <node> def_arg columnElem where_clause where_or_current_clause
|
%type <node> def_arg columnElem where_clause where_or_current_clause
|
||||||
a_expr b_expr c_expr func_expr AexprConst indirection_el
|
a_expr b_expr c_expr func_expr AexprConst indirection_el
|
||||||
columnref in_expr having_clause func_table array_expr
|
columnref in_expr having_clause func_table array_expr
|
||||||
@ -1781,7 +1784,7 @@ alter_table_cmd:
|
|||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
/* ALTER TABLE <name> SET (...) */
|
/* ALTER TABLE <name> SET (...) */
|
||||||
| SET definition
|
| SET reloptions
|
||||||
{
|
{
|
||||||
AlterTableCmd *n = makeNode(AlterTableCmd);
|
AlterTableCmd *n = makeNode(AlterTableCmd);
|
||||||
n->subtype = AT_SetRelOptions;
|
n->subtype = AT_SetRelOptions;
|
||||||
@ -1789,7 +1792,7 @@ alter_table_cmd:
|
|||||||
$$ = (Node *)n;
|
$$ = (Node *)n;
|
||||||
}
|
}
|
||||||
/* ALTER TABLE <name> RESET (...) */
|
/* ALTER TABLE <name> RESET (...) */
|
||||||
| RESET definition
|
| RESET reloptions
|
||||||
{
|
{
|
||||||
AlterTableCmd *n = makeNode(AlterTableCmd);
|
AlterTableCmd *n = makeNode(AlterTableCmd);
|
||||||
n->subtype = AT_ResetRelOptions;
|
n->subtype = AT_ResetRelOptions;
|
||||||
@ -1814,6 +1817,37 @@ alter_using:
|
|||||||
| /* EMPTY */ { $$ = NULL; }
|
| /* EMPTY */ { $$ = NULL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
reloptions:
|
||||||
|
'(' reloption_list ')' { $$ = $2; }
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_reloptions: WITH reloptions { $$ = $2; }
|
||||||
|
| /* EMPTY */ { $$ = NIL; }
|
||||||
|
;
|
||||||
|
|
||||||
|
reloption_list:
|
||||||
|
reloption_elem { $$ = list_make1($1); }
|
||||||
|
| reloption_list ',' reloption_elem { $$ = lappend($1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
reloption_elem:
|
||||||
|
ColLabel '=' def_arg
|
||||||
|
{
|
||||||
|
$$ = makeReloptElem($1, NULL, (Node *) $3);
|
||||||
|
}
|
||||||
|
| ColLabel
|
||||||
|
{
|
||||||
|
$$ = makeReloptElem($1, NULL, NULL);
|
||||||
|
}
|
||||||
|
| ColLabel '.' ColLabel '=' def_arg
|
||||||
|
{
|
||||||
|
$$ = makeReloptElem($3, $1, (Node *) $5);
|
||||||
|
}
|
||||||
|
| ColLabel '.' ColLabel
|
||||||
|
{
|
||||||
|
$$ = makeReloptElem($3, $1, NULL);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
@ -2440,9 +2474,9 @@ OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; }
|
|||||||
|
|
||||||
/* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */
|
/* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */
|
||||||
OptWith:
|
OptWith:
|
||||||
WITH definition { $$ = $2; }
|
WITH reloptions { $$ = $2; }
|
||||||
| WITH OIDS { $$ = list_make1(defWithOids(true)); }
|
| WITH OIDS { $$ = list_make1(reloptWithOids(true)); }
|
||||||
| WITHOUT OIDS { $$ = list_make1(defWithOids(false)); }
|
| WITHOUT OIDS { $$ = list_make1(reloptWithOids(false)); }
|
||||||
| /*EMPTY*/ { $$ = NIL; }
|
| /*EMPTY*/ { $$ = NIL; }
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -4473,7 +4507,7 @@ opt_granted_by: GRANTED BY RoleId { $$ = $3; }
|
|||||||
|
|
||||||
IndexStmt: CREATE index_opt_unique INDEX index_name
|
IndexStmt: CREATE index_opt_unique INDEX index_name
|
||||||
ON qualified_name access_method_clause '(' index_params ')'
|
ON qualified_name access_method_clause '(' index_params ')'
|
||||||
opt_definition OptTableSpace where_clause
|
opt_reloptions OptTableSpace where_clause
|
||||||
{
|
{
|
||||||
IndexStmt *n = makeNode(IndexStmt);
|
IndexStmt *n = makeNode(IndexStmt);
|
||||||
n->unique = $2;
|
n->unique = $2;
|
||||||
@ -4489,7 +4523,7 @@ IndexStmt: CREATE index_opt_unique INDEX index_name
|
|||||||
}
|
}
|
||||||
| CREATE index_opt_unique INDEX CONCURRENTLY index_name
|
| CREATE index_opt_unique INDEX CONCURRENTLY index_name
|
||||||
ON qualified_name access_method_clause '(' index_params ')'
|
ON qualified_name access_method_clause '(' index_params ')'
|
||||||
opt_definition OptTableSpace where_clause
|
opt_reloptions OptTableSpace where_clause
|
||||||
{
|
{
|
||||||
IndexStmt *n = makeNode(IndexStmt);
|
IndexStmt *n = makeNode(IndexStmt);
|
||||||
n->unique = $2;
|
n->unique = $2;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.186 2009/01/22 20:16:05 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.187 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -233,7 +233,7 @@ interpretInhOption(InhOption inhOpt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a relation-options list (of DefElems), return true iff the specified
|
* Given a relation-options list (of ReloptElems), return true iff the specified
|
||||||
* table/result set should be created with OIDs. This needs to be done after
|
* table/result set should be created with OIDs. This needs to be done after
|
||||||
* parsing the query string because the return value can depend upon the
|
* parsing the query string because the return value can depend upon the
|
||||||
* default_with_oids GUC var.
|
* default_with_oids GUC var.
|
||||||
@ -246,10 +246,10 @@ interpretOidsOption(List *defList)
|
|||||||
/* Scan list to see if OIDS was included */
|
/* Scan list to see if OIDS was included */
|
||||||
foreach(cell, defList)
|
foreach(cell, defList)
|
||||||
{
|
{
|
||||||
DefElem *def = (DefElem *) lfirst(cell);
|
ReloptElem *def = (ReloptElem *) lfirst(cell);
|
||||||
|
|
||||||
if (pg_strcasecmp(def->defname, "oids") == 0)
|
if (pg_strcasecmp(def->optname, "oids") == 0)
|
||||||
return defGetBoolean(def);
|
return reloptGetBoolean(def);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OIDS option was not specified, so use default. */
|
/* OIDS option was not specified, so use default. */
|
||||||
|
@ -10,12 +10,13 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.305 2009/01/22 20:16:06 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.306 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "access/reloptions.h"
|
||||||
#include "access/twophase.h"
|
#include "access/twophase.h"
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
#include "catalog/catalog.h"
|
#include "catalog/catalog.h"
|
||||||
@ -422,6 +423,9 @@ ProcessUtility(Node *parsetree,
|
|||||||
|
|
||||||
if (IsA(stmt, CreateStmt))
|
if (IsA(stmt, CreateStmt))
|
||||||
{
|
{
|
||||||
|
Datum toast_options;
|
||||||
|
static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
|
||||||
|
|
||||||
/* Create the table itself */
|
/* Create the table itself */
|
||||||
relOid = DefineRelation((CreateStmt *) stmt,
|
relOid = DefineRelation((CreateStmt *) stmt,
|
||||||
RELKIND_RELATION);
|
RELKIND_RELATION);
|
||||||
@ -431,7 +435,17 @@ ProcessUtility(Node *parsetree,
|
|||||||
* needs a secondary relation too.
|
* needs a secondary relation too.
|
||||||
*/
|
*/
|
||||||
CommandCounterIncrement();
|
CommandCounterIncrement();
|
||||||
AlterTableCreateToastTable(relOid);
|
|
||||||
|
/* parse and validate reloptions for the toast table */
|
||||||
|
toast_options = transformRelOptions((Datum) 0,
|
||||||
|
((CreateStmt *)stmt)->options,
|
||||||
|
"toast",
|
||||||
|
validnsps,
|
||||||
|
true, false);
|
||||||
|
(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
|
||||||
|
true);
|
||||||
|
|
||||||
|
AlterTableCreateToastTable(relOid, toast_options);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* by PostgreSQL
|
* by PostgreSQL
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.517 2009/01/27 12:40:15 petere Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.518 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -3100,6 +3100,7 @@ getTables(int *numTables)
|
|||||||
int i_owning_col;
|
int i_owning_col;
|
||||||
int i_reltablespace;
|
int i_reltablespace;
|
||||||
int i_reloptions;
|
int i_reloptions;
|
||||||
|
int i_toastreloptions;
|
||||||
|
|
||||||
/* Make sure we are in proper schema */
|
/* Make sure we are in proper schema */
|
||||||
selectSourceSchema("pg_catalog");
|
selectSourceSchema("pg_catalog");
|
||||||
@ -3131,22 +3132,24 @@ getTables(int *numTables)
|
|||||||
* owning column, if any (note this dependency is AUTO as of 8.2)
|
* owning column, if any (note this dependency is AUTO as of 8.2)
|
||||||
*/
|
*/
|
||||||
appendPQExpBuffer(query,
|
appendPQExpBuffer(query,
|
||||||
"SELECT c.tableoid, c.oid, relname, "
|
"SELECT c.tableoid, c.oid, c.relname, "
|
||||||
"relacl, relkind, relnamespace, "
|
"c.relacl, c.relkind, c.relnamespace, "
|
||||||
"(%s relowner) as rolname, "
|
"(%s c.relowner) as rolname, "
|
||||||
"relchecks, relhastriggers, "
|
"c.relchecks, c.relhastriggers, "
|
||||||
"relhasindex, relhasrules, relhasoids, "
|
"c.relhasindex, c.relhasrules, c.relhasoids, "
|
||||||
"d.refobjid as owning_tab, "
|
"d.refobjid as owning_tab, "
|
||||||
"d.refobjsubid as owning_col, "
|
"d.refobjsubid as owning_col, "
|
||||||
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
|
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
|
||||||
"array_to_string(c.reloptions, ', ') as reloptions "
|
"array_to_string(c.reloptions, ', ') as reloptions, "
|
||||||
|
"array_to_string(array(select 'toast.' || x from unnest(tc.reloptions) x), ', ') as toast_reloptions "
|
||||||
"from pg_class c "
|
"from pg_class c "
|
||||||
"left join pg_depend d on "
|
"left join pg_depend d on "
|
||||||
"(c.relkind = '%c' and "
|
"(c.relkind = '%c' and "
|
||||||
"d.classid = c.tableoid and d.objid = c.oid and "
|
"d.classid = c.tableoid and d.objid = c.oid and "
|
||||||
"d.objsubid = 0 and "
|
"d.objsubid = 0 and "
|
||||||
"d.refclassid = c.tableoid and d.deptype = 'a') "
|
"d.refclassid = c.tableoid and d.deptype = 'a') "
|
||||||
"where relkind in ('%c', '%c', '%c', '%c') "
|
"left join pg_class tc on (c.reltoastrelid = tc.oid) "
|
||||||
|
"where c.relkind in ('%c', '%c', '%c', '%c') "
|
||||||
"order by c.oid",
|
"order by c.oid",
|
||||||
username_subquery,
|
username_subquery,
|
||||||
RELKIND_SEQUENCE,
|
RELKIND_SEQUENCE,
|
||||||
@ -3168,7 +3171,8 @@ getTables(int *numTables)
|
|||||||
"d.refobjid as owning_tab, "
|
"d.refobjid as owning_tab, "
|
||||||
"d.refobjsubid as owning_col, "
|
"d.refobjsubid as owning_col, "
|
||||||
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
|
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
|
||||||
"array_to_string(c.reloptions, ', ') as reloptions "
|
"array_to_string(c.reloptions, ', ') as reloptions, "
|
||||||
|
"NULL as toast_reloptions "
|
||||||
"from pg_class c "
|
"from pg_class c "
|
||||||
"left join pg_depend d on "
|
"left join pg_depend d on "
|
||||||
"(c.relkind = '%c' and "
|
"(c.relkind = '%c' and "
|
||||||
@ -3197,7 +3201,8 @@ getTables(int *numTables)
|
|||||||
"d.refobjid as owning_tab, "
|
"d.refobjid as owning_tab, "
|
||||||
"d.refobjsubid as owning_col, "
|
"d.refobjsubid as owning_col, "
|
||||||
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
|
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
|
||||||
"NULL as reloptions "
|
"NULL as reloptions, "
|
||||||
|
"NULL as toast_reloptions "
|
||||||
"from pg_class c "
|
"from pg_class c "
|
||||||
"left join pg_depend d on "
|
"left join pg_depend d on "
|
||||||
"(c.relkind = '%c' and "
|
"(c.relkind = '%c' and "
|
||||||
@ -3226,7 +3231,8 @@ getTables(int *numTables)
|
|||||||
"d.refobjid as owning_tab, "
|
"d.refobjid as owning_tab, "
|
||||||
"d.refobjsubid as owning_col, "
|
"d.refobjsubid as owning_col, "
|
||||||
"NULL as reltablespace, "
|
"NULL as reltablespace, "
|
||||||
"NULL as reloptions "
|
"NULL as reloptions, "
|
||||||
|
"NULL as toast_reloptions "
|
||||||
"from pg_class c "
|
"from pg_class c "
|
||||||
"left join pg_depend d on "
|
"left join pg_depend d on "
|
||||||
"(c.relkind = '%c' and "
|
"(c.relkind = '%c' and "
|
||||||
@ -3251,7 +3257,8 @@ getTables(int *numTables)
|
|||||||
"NULL::oid as owning_tab, "
|
"NULL::oid as owning_tab, "
|
||||||
"NULL::int4 as owning_col, "
|
"NULL::int4 as owning_col, "
|
||||||
"NULL as reltablespace, "
|
"NULL as reltablespace, "
|
||||||
"NULL as reloptions "
|
"NULL as reloptions, "
|
||||||
|
"NULL as toast_reloptions "
|
||||||
"from pg_class "
|
"from pg_class "
|
||||||
"where relkind in ('%c', '%c', '%c') "
|
"where relkind in ('%c', '%c', '%c') "
|
||||||
"order by oid",
|
"order by oid",
|
||||||
@ -3271,7 +3278,8 @@ getTables(int *numTables)
|
|||||||
"NULL::oid as owning_tab, "
|
"NULL::oid as owning_tab, "
|
||||||
"NULL::int4 as owning_col, "
|
"NULL::int4 as owning_col, "
|
||||||
"NULL as reltablespace, "
|
"NULL as reltablespace, "
|
||||||
"NULL as reloptions "
|
"NULL as reloptions, "
|
||||||
|
"NULL as toast_reloptions "
|
||||||
"from pg_class "
|
"from pg_class "
|
||||||
"where relkind in ('%c', '%c', '%c') "
|
"where relkind in ('%c', '%c', '%c') "
|
||||||
"order by oid",
|
"order by oid",
|
||||||
@ -3301,7 +3309,8 @@ getTables(int *numTables)
|
|||||||
"NULL::oid as owning_tab, "
|
"NULL::oid as owning_tab, "
|
||||||
"NULL::int4 as owning_col, "
|
"NULL::int4 as owning_col, "
|
||||||
"NULL as reltablespace, "
|
"NULL as reltablespace, "
|
||||||
"NULL as reloptions "
|
"NULL as reloptions, "
|
||||||
|
"NULL as toast_reloptions "
|
||||||
"from pg_class c "
|
"from pg_class c "
|
||||||
"where relkind in ('%c', '%c') "
|
"where relkind in ('%c', '%c') "
|
||||||
"order by oid",
|
"order by oid",
|
||||||
@ -3344,6 +3353,7 @@ getTables(int *numTables)
|
|||||||
i_owning_col = PQfnumber(res, "owning_col");
|
i_owning_col = PQfnumber(res, "owning_col");
|
||||||
i_reltablespace = PQfnumber(res, "reltablespace");
|
i_reltablespace = PQfnumber(res, "reltablespace");
|
||||||
i_reloptions = PQfnumber(res, "reloptions");
|
i_reloptions = PQfnumber(res, "reloptions");
|
||||||
|
i_toastreloptions = PQfnumber(res, "toast_reloptions");
|
||||||
|
|
||||||
if (lockWaitTimeout && g_fout->remoteVersion >= 70300)
|
if (lockWaitTimeout && g_fout->remoteVersion >= 70300)
|
||||||
{
|
{
|
||||||
@ -3389,6 +3399,7 @@ getTables(int *numTables)
|
|||||||
}
|
}
|
||||||
tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
|
tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
|
||||||
tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
|
tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
|
||||||
|
tblinfo[i].toast_reloptions = strdup(PQgetvalue(res, i, i_toastreloptions));
|
||||||
|
|
||||||
/* other fields were zeroed above */
|
/* other fields were zeroed above */
|
||||||
|
|
||||||
@ -9700,8 +9711,24 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
|
|||||||
appendPQExpBuffer(q, ")");
|
appendPQExpBuffer(q, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((tbinfo->reloptions && strlen(tbinfo->reloptions) > 0) ||
|
||||||
|
(tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0))
|
||||||
|
{
|
||||||
|
bool addcomma = false;
|
||||||
|
|
||||||
|
appendPQExpBuffer(q, "\nWITH (");
|
||||||
if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
|
if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
|
||||||
appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions);
|
{
|
||||||
|
addcomma = true;
|
||||||
|
appendPQExpBuffer(q, "%s", tbinfo->reloptions);
|
||||||
|
}
|
||||||
|
if (tbinfo->toast_reloptions && strlen(tbinfo->toast_reloptions) > 0)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(q, "%s%s", addcomma ? ", " : "",
|
||||||
|
tbinfo->toast_reloptions);
|
||||||
|
}
|
||||||
|
appendPQExpBuffer(q, ")");
|
||||||
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(q, ";\n");
|
appendPQExpBuffer(q, ";\n");
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.149 2009/01/27 12:40:15 petere Exp $
|
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.150 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -221,6 +221,7 @@ typedef struct _tableInfo
|
|||||||
char relkind;
|
char relkind;
|
||||||
char *reltablespace; /* relation tablespace */
|
char *reltablespace; /* relation tablespace */
|
||||||
char *reloptions; /* options specified by WITH (...) */
|
char *reloptions; /* options specified by WITH (...) */
|
||||||
|
char *toast_reloptions; /* ditto, for the TOAST table */
|
||||||
bool hasindex; /* does it have any indexes? */
|
bool hasindex; /* does it have any indexes? */
|
||||||
bool hasrules; /* does it have any rules? */
|
bool hasrules; /* does it have any rules? */
|
||||||
bool hastriggers; /* does it have any triggers? */
|
bool hastriggers; /* does it have any triggers? */
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.11 2009/01/26 19:41:06 alvherre Exp $
|
* $PostgreSQL: pgsql/src/include/access/reloptions.h,v 1.12 2009/02/02 19:31:39 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -44,6 +44,9 @@ typedef enum relopt_kind
|
|||||||
RELOPT_KIND_MAX = 255
|
RELOPT_KIND_MAX = 255
|
||||||
} relopt_kind;
|
} relopt_kind;
|
||||||
|
|
||||||
|
/* reloption namespaces allowed for heaps -- currently only TOAST */
|
||||||
|
#define HEAP_RELOPT_NAMESPACES { "toast", NULL }
|
||||||
|
|
||||||
/* generic struct to hold shared data */
|
/* generic struct to hold shared data */
|
||||||
typedef struct relopt_gen
|
typedef struct relopt_gen
|
||||||
{
|
{
|
||||||
@ -240,6 +243,7 @@ extern void add_string_reloption(int kind, char *name, char *desc,
|
|||||||
char *default_val, validate_string_relopt validator);
|
char *default_val, validate_string_relopt validator);
|
||||||
|
|
||||||
extern Datum transformRelOptions(Datum oldOptions, List *defList,
|
extern Datum transformRelOptions(Datum oldOptions, List *defList,
|
||||||
|
char *namspace, char *validnsps[],
|
||||||
bool ignoreOids, bool isReset);
|
bool ignoreOids, bool isReset);
|
||||||
extern List *untransformRelOptions(Datum options);
|
extern List *untransformRelOptions(Datum options);
|
||||||
extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
|
extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/catalog/toasting.h,v 1.5 2009/01/01 17:23:58 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/catalog/toasting.h,v 1.6 2009/02/02 19:31:40 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -17,7 +17,7 @@
|
|||||||
/*
|
/*
|
||||||
* toasting.c prototypes
|
* toasting.c prototypes
|
||||||
*/
|
*/
|
||||||
extern void AlterTableCreateToastTable(Oid relOid);
|
extern void AlterTableCreateToastTable(Oid relOid, Datum reloptions);
|
||||||
extern void BootstrapToastTable(char *relName,
|
extern void BootstrapToastTable(char *relName,
|
||||||
Oid toastOid, Oid toastIndexOid);
|
Oid toastOid, Oid toastIndexOid);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.92 2009/01/01 17:23:58 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.93 2009/02/02 19:31:40 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -145,6 +145,8 @@ extern int64 defGetInt64(DefElem *def);
|
|||||||
extern List *defGetQualifiedName(DefElem *def);
|
extern List *defGetQualifiedName(DefElem *def);
|
||||||
extern TypeName *defGetTypeName(DefElem *def);
|
extern TypeName *defGetTypeName(DefElem *def);
|
||||||
extern int defGetTypeLength(DefElem *def);
|
extern int defGetTypeLength(DefElem *def);
|
||||||
extern DefElem *defWithOids(bool value);
|
extern char *reloptGetString(ReloptElem *relopt);
|
||||||
|
extern bool reloptGetBoolean(ReloptElem *relopt);
|
||||||
|
extern ReloptElem *reloptWithOids(bool value);
|
||||||
|
|
||||||
#endif /* DEFREM_H */
|
#endif /* DEFREM_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.65 2009/01/01 17:24:00 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/makefuncs.h,v 1.66 2009/02/02 19:31:40 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -69,4 +69,6 @@ extern DefElem *makeDefElem(char *name, Node *arg);
|
|||||||
|
|
||||||
extern OptionDefElem *makeOptionDefElem(int op, DefElem *def);
|
extern OptionDefElem *makeOptionDefElem(int op, DefElem *def);
|
||||||
|
|
||||||
|
extern ReloptElem *makeReloptElem(char *name, char *namspc, Node *arg);
|
||||||
|
|
||||||
#endif /* MAKEFUNC_H */
|
#endif /* MAKEFUNC_H */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.219 2009/01/22 20:16:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.220 2009/02/02 19:31:40 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -363,6 +363,7 @@ typedef enum NodeTag
|
|||||||
T_Constraint,
|
T_Constraint,
|
||||||
T_DefElem,
|
T_DefElem,
|
||||||
T_OptionDefElem,
|
T_OptionDefElem,
|
||||||
|
T_ReloptElem,
|
||||||
T_RangeTblEntry,
|
T_RangeTblEntry,
|
||||||
T_SortGroupClause,
|
T_SortGroupClause,
|
||||||
T_WindowClause,
|
T_WindowClause,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.389 2009/01/22 20:16:09 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.390 2009/02/02 19:31:40 alvherre Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -532,6 +532,17 @@ typedef struct OptionDefElem
|
|||||||
DefElem *def; /* The actual definition */
|
DefElem *def; /* The actual definition */
|
||||||
} OptionDefElem;
|
} OptionDefElem;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reloption definition. As DefElem, with optional option namespace.
|
||||||
|
*/
|
||||||
|
typedef struct ReloptElem
|
||||||
|
{
|
||||||
|
NodeTag type;
|
||||||
|
char *nmspc;
|
||||||
|
char *optname;
|
||||||
|
Node *arg;
|
||||||
|
} ReloptElem;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* LockingClause - raw representation of FOR UPDATE/SHARE options
|
* LockingClause - raw representation of FOR UPDATE/SHARE options
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user