Add FILLFACTOR to CREATE INDEX.
ITAGAKI Takahiro
This commit is contained in:
parent
5d5c1416bf
commit
277807bd9e
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_index.sgml,v 1.8 2006/02/12 19:11:00 momjian Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_index.sgml,v 1.9 2006/07/02 02:23:17 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -22,6 +22,8 @@ PostgreSQL documentation
|
||||
<synopsis>
|
||||
ALTER INDEX <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable class="PARAMETER">new_name</replaceable>
|
||||
ALTER INDEX <replaceable class="PARAMETER">name</replaceable> SET TABLESPACE <replaceable class="PARAMETER">tablespace_name</replaceable>
|
||||
ALTER INDEX <replaceable class="PARAMETER">name</replaceable> SET (FILLFACTOR = <replaceable class="PARAMETER">fillfactor</replaceable>)
|
||||
ALTER INDEX <replaceable class="PARAMETER">name</replaceable> RESET (FILLFACTOR)
|
||||
</synopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@ -56,6 +58,26 @@ ALTER INDEX <replaceable class="PARAMETER">name</replaceable> SET TABLESPACE <re
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>SET (FILLFACTOR)</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This form changes the index's fillfactor to the specified percentage.
|
||||
Index structure is not modified immediately; use <literal>REINDEX</literal>
|
||||
to ensure reflection of the change.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>RESET (FILLFACTOR)</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This form changes the index's fillfactor to the default value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.85 2006/07/02 01:58:36 momjian Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.86 2006/07/02 02:23:17 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -46,6 +46,8 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
|
||||
CLUSTER ON <replaceable class="PARAMETER">index_name</replaceable>
|
||||
SET WITHOUT CLUSTER
|
||||
SET WITHOUT OIDS
|
||||
SET (FILLFACTOR = <replaceable class="PARAMETER">fillfactor</replaceable>)
|
||||
RESET (FILLFACTOR)
|
||||
INHERIT <replaceable class="PARAMETER">parent_table</replaceable>
|
||||
NO INHERIT <replaceable class="PARAMETER">parent_table</replaceable>
|
||||
OWNER TO <replaceable class="PARAMETER">new_owner</replaceable>
|
||||
@ -321,6 +323,26 @@ where <replaceable class="PARAMETER">action</replaceable> is one of:
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>SET (FILLFACTOR)</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This form changes the table's fillfactor to the specified percentage.
|
||||
Table structure is not modified immediately; use <literal>CLUSTER</literal>
|
||||
to ensure reflection of the change.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>RESET</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This form changes the table's fillfactor to the default value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>RENAME</literal></term>
|
||||
<listitem>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.52 2005/11/07 17:36:44 tgl Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_index.sgml,v 1.53 2006/07/02 02:23:17 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -22,6 +22,7 @@ PostgreSQL documentation
|
||||
<synopsis>
|
||||
CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <replaceable class="parameter">table</replaceable> [ USING <replaceable class="parameter">method</replaceable> ]
|
||||
( { <replaceable class="parameter">column</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ <replaceable class="parameter">opclass</replaceable> ] [, ...] )
|
||||
[ WITH (FILLFACTOR = <replaceable>fillfactor</replaceable>) ]
|
||||
[ TABLESPACE <replaceable class="parameter">tablespace</replaceable> ]
|
||||
[ WHERE <replaceable class="parameter">predicate</replaceable> ]
|
||||
</synopsis>
|
||||
@ -171,6 +172,15 @@ CREATE [ UNIQUE ] INDEX <replaceable class="parameter">name</replaceable> ON <re
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">fillfactor</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
The index's fillfactor in percentage.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable class="parameter">tablespace</replaceable></term>
|
||||
<listitem>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.102 2006/06/28 22:01:52 neilc Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.103 2006/07/02 02:23:17 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -28,6 +28,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable class="PAR
|
||||
] )
|
||||
[ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
|
||||
[ WITH OIDS | WITHOUT OIDS ]
|
||||
[ WITH (FILLFACTOR = <replaceable>fillfactor</replaceable>) ]
|
||||
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
|
||||
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
|
||||
|
||||
@ -303,6 +304,15 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>WITH (FILLFACTOR = <replaceable>fillfactor</replaceable>)</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This optional clause specifies the table's fillfactor in percentage.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable></literal></term>
|
||||
<listitem>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.32 2006/02/19 00:04:26 neilc Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table_as.sgml,v 1.33 2006/07/02 02:23:18 momjian Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
@ -23,6 +23,7 @@ PostgreSQL documentation
|
||||
CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name</replaceable>
|
||||
[ (<replaceable>column_name</replaceable> [, ...] ) ]
|
||||
[ WITH OIDS | WITHOUT OIDS ]
|
||||
[ WITH (FILLFACTOR = <replaceable>fillfactor</replaceable>) ]
|
||||
[ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
|
||||
[ TABLESPACE <replaceable class="PARAMETER">tablespace</replaceable> ]
|
||||
AS <replaceable>query</replaceable>
|
||||
@ -116,6 +117,15 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } ] TABLE <replaceable>table_name
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>WITH (FILLFACTOR = <replaceable>fillfactor</replaceable>)</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
This optional clause specifies the table's fillfactor in percentage.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>ON COMMIT</literal></term>
|
||||
<listitem>
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.107 2006/06/27 02:51:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/common/heaptuple.c,v 1.108 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1738,3 +1738,54 @@ heap_addheader(int natts, /* max domain index */
|
||||
|
||||
return tuple;
|
||||
}
|
||||
|
||||
/*
|
||||
* build_class_tuple
|
||||
*
|
||||
* XXX Natts_pg_class_fixed is a hack - see pg_class.h
|
||||
*/
|
||||
HeapTuple
|
||||
build_class_tuple(Form_pg_class pgclass, ArrayType *options)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
HeapTupleHeader td;
|
||||
Form_pg_class data; /* contents of tuple */
|
||||
Size len;
|
||||
Size size;
|
||||
int hoff;
|
||||
|
||||
/* size of pg_class tuple with options */
|
||||
if (options)
|
||||
size = offsetof(FormData_pg_class, reloptions) + VARATT_SIZE(options);
|
||||
else
|
||||
size = CLASS_TUPLE_SIZE;
|
||||
|
||||
/* header needs no null bitmap */
|
||||
hoff = offsetof(HeapTupleHeaderData, t_bits);
|
||||
hoff += sizeof(Oid);
|
||||
hoff = MAXALIGN(hoff);
|
||||
len = hoff + size;
|
||||
|
||||
tuple = (HeapTuple) palloc0(HEAPTUPLESIZE + len);
|
||||
tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
|
||||
|
||||
tuple->t_len = len;
|
||||
ItemPointerSetInvalid(&(tuple->t_self));
|
||||
tuple->t_tableOid = InvalidOid;
|
||||
|
||||
/* we don't bother to fill the Datum fields */
|
||||
|
||||
td->t_natts = Natts_pg_class_fixed;
|
||||
td->t_hoff = hoff;
|
||||
td->t_infomask = HEAP_HASOID;
|
||||
|
||||
data = (Form_pg_class) ((char *) td + hoff);
|
||||
memcpy(data, pgclass, CLASS_TUPLE_SIZE);
|
||||
if (options)
|
||||
{
|
||||
td->t_natts++;
|
||||
memcpy(data->reloptions, options, VARATT_SIZE(options));
|
||||
}
|
||||
|
||||
return tuple;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.1 2006/05/02 11:28:54 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gin/ginutil.c,v 1.2 2006/07/02 02:23:18 momjian Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -201,3 +201,17 @@ GinPageGetCopyPage( Page page ) {
|
||||
|
||||
return tmppage;
|
||||
}
|
||||
|
||||
Datum
|
||||
ginoption(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
|
||||
|
||||
if (options != NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("GIN does not support parameters at all")));
|
||||
|
||||
/* Do not use PG_RETURN_NULL. */
|
||||
PG_RETURN_BYTEA_P(NULL);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.139 2006/06/28 12:00:14 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gist.c,v 1.140 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -44,6 +44,7 @@ static void gistbuildCallback(Relation index,
|
||||
void *state);
|
||||
static void gistdoinsert(Relation r,
|
||||
IndexTuple itup,
|
||||
Size freespace,
|
||||
GISTSTATE *GISTstate);
|
||||
static void gistfindleaf(GISTInsertState *state,
|
||||
GISTSTATE *giststate);
|
||||
@ -197,7 +198,8 @@ gistbuildCallback(Relation index,
|
||||
* you're inserting single tups, but not when you're initializing the
|
||||
* whole index at once.
|
||||
*/
|
||||
gistdoinsert(index, itup, &buildstate->giststate);
|
||||
gistdoinsert(index, itup, IndexGetPageFreeSpace(index),
|
||||
&buildstate->giststate);
|
||||
|
||||
buildstate->indtuples += 1;
|
||||
MemoryContextSwitchTo(oldCtx);
|
||||
@ -236,7 +238,7 @@ gistinsert(PG_FUNCTION_ARGS)
|
||||
values, isnull, true /* size is currently bogus */);
|
||||
itup->t_tid = *ht_ctid;
|
||||
|
||||
gistdoinsert(r, itup, &giststate);
|
||||
gistdoinsert(r, itup, 0, &giststate);
|
||||
|
||||
/* cleanup */
|
||||
freeGISTstate(&giststate);
|
||||
@ -253,7 +255,7 @@ gistinsert(PG_FUNCTION_ARGS)
|
||||
* so it does not bother releasing palloc'd allocations.
|
||||
*/
|
||||
static void
|
||||
gistdoinsert(Relation r, IndexTuple itup, GISTSTATE *giststate)
|
||||
gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate)
|
||||
{
|
||||
GISTInsertState state;
|
||||
|
||||
@ -263,6 +265,7 @@ gistdoinsert(Relation r, IndexTuple itup, GISTSTATE *giststate)
|
||||
state.itup[0] = (IndexTuple) palloc(IndexTupleSize(itup));
|
||||
memcpy(state.itup[0], itup, IndexTupleSize(itup));
|
||||
state.ituplen = 1;
|
||||
state.freespace = freespace;
|
||||
state.r = r;
|
||||
state.key = itup->t_tid;
|
||||
state.needInsertComplete = true;
|
||||
@ -294,7 +297,11 @@ gistplacetopage(GISTInsertState *state, GISTSTATE *giststate)
|
||||
*/
|
||||
|
||||
|
||||
if (gistnospace(state->stack->page, state->itup, state->ituplen, (is_leaf) ? InvalidOffsetNumber : state->stack->childoffnum))
|
||||
/*
|
||||
* XXX: If we want to change fillfactors between node and leaf,
|
||||
* fillfactor = (is_leaf ? state->leaf_fillfactor : state->node_fillfactor)
|
||||
*/
|
||||
if (gistnospace(state->stack->page, state->itup, state->ituplen, (is_leaf) ? InvalidOffsetNumber : state->stack->childoffnum, state->freespace))
|
||||
{
|
||||
/* no space for insertion */
|
||||
IndexTuple *itvec;
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.16 2006/06/28 12:00:14 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistutil.c,v 1.17 2006/07/02 02:23:18 momjian Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@ -58,9 +58,9 @@ gistfillbuffer(Relation r, Page page, IndexTuple *itup,
|
||||
* Check space for itup vector on page
|
||||
*/
|
||||
bool
|
||||
gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete)
|
||||
gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace)
|
||||
{
|
||||
unsigned int size = 0, deleted = 0;
|
||||
unsigned int size = freespace, deleted = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
@ -82,6 +82,7 @@ gistfitpage(IndexTuple *itvec, int len) {
|
||||
for(i=0;i<len;i++)
|
||||
size += IndexTupleSize(itvec[i]) + sizeof(ItemIdData);
|
||||
|
||||
/* TODO: Consider fillfactor */
|
||||
return (size <= GiSTPageSize);
|
||||
}
|
||||
|
||||
@ -634,3 +635,16 @@ gistNewBuffer(Relation r)
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Datum
|
||||
gistoption(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#define GIST_DEFAULT_FILLFACTOR 90
|
||||
#define GIST_MIN_FILLFACTOR 50
|
||||
|
||||
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
|
||||
|
||||
/* Use index common routine. */
|
||||
PG_RETURN_BYTEA_P(genam_option(options,
|
||||
GIST_MIN_FILLFACTOR, GIST_DEFAULT_FILLFACTOR));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.22 2006/05/19 11:10:25 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistvacuum.c,v 1.23 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -376,7 +376,7 @@ gistVacuumUpdate(GistVacuum *gv, BlockNumber blkno, bool needunion)
|
||||
if (curlenaddon)
|
||||
{
|
||||
/* insert updated tuples */
|
||||
if (gistnospace(tempPage, addon, curlenaddon, InvalidOffsetNumber)) {
|
||||
if (gistnospace(tempPage, addon, curlenaddon, InvalidOffsetNumber, 0)) {
|
||||
/* there is no space on page to insert tuples */
|
||||
res = vacuumSplitPage(gv, tempPage, buffer, addon, curlenaddon);
|
||||
tempPage=NULL; /* vacuumSplitPage() free tempPage */
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.20 2006/05/19 17:15:41 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/gist/gistxlog.c,v 1.21 2006/07/02 02:23:18 momjian Exp $
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
@ -690,7 +690,7 @@ gistContinueInsert(gistIncompleteInsert *insert)
|
||||
* that wiil be enough space....
|
||||
*/
|
||||
|
||||
if (gistnospace(pages[0], itup, lenitup, *todelete))
|
||||
if (gistnospace(pages[0], itup, lenitup, *todelete, 0))
|
||||
{
|
||||
|
||||
/* no space left on page, so we must split */
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/hash/hashpage.c,v 1.57 2006/03/31 23:32:05 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/hash/hashpage.c,v 1.58 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Postgres hash pages look like ordinary relation pages. The opaque
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#include "access/genam.h"
|
||||
#include "access/hash.h"
|
||||
#include "catalog/index.h"
|
||||
#include "miscadmin.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/lsyscache.h"
|
||||
@ -231,7 +232,7 @@ _hash_metapinit(Relation rel)
|
||||
RelationGetDescr(rel)->attrs[0]->atttypmod);
|
||||
item_width = MAXALIGN(sizeof(IndexTupleData)) + MAXALIGN(data_width) +
|
||||
sizeof(ItemIdData); /* include the line pointer */
|
||||
ffactor = (BLCKSZ * 3 / 4) / item_width;
|
||||
ffactor = BLCKSZ * IndexGetFillFactor(rel) / 100 / item_width;
|
||||
/* keep to a sane range */
|
||||
if (ffactor < 10)
|
||||
ffactor = 10;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/hash/hashutil.c,v 1.47 2006/03/05 15:58:21 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/hash/hashutil.c,v 1.48 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -173,3 +173,16 @@ _hash_checkpage(Relation rel, Buffer buf, int flags)
|
||||
errhint("Please REINDEX it.")));
|
||||
}
|
||||
}
|
||||
|
||||
Datum
|
||||
hashoption(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#define HASH_MIN_FILLFACTOR 50
|
||||
#define HASH_DEFAULT_FILLFACTOR 75
|
||||
|
||||
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
|
||||
|
||||
/* Use index common routine. */
|
||||
PG_RETURN_BYTEA_P(genam_option(options,
|
||||
HASH_MIN_FILLFACTOR, HASH_DEFAULT_FILLFACTOR));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.213 2006/05/28 02:27:08 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.214 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -46,9 +46,13 @@
|
||||
#include "access/xlogutils.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "pgstat.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "utils/catcache.h"
|
||||
#include "utils/inval.h"
|
||||
#include "utils/relcache.h"
|
||||
|
||||
@ -3588,3 +3592,59 @@ heap_desc(StringInfo buf, uint8 xl_info, char *rec)
|
||||
else
|
||||
appendStringInfo(buf, "UNKNOWN");
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse options for heaps.
|
||||
*
|
||||
* relkind Kind of relation
|
||||
* options Options as text[]
|
||||
*/
|
||||
bytea *
|
||||
heap_option(char relkind, ArrayType *options)
|
||||
{
|
||||
/*
|
||||
* XXX: What fillfactor should be default?
|
||||
* overriding databases:
|
||||
* - Oracle, DB2 = 90%
|
||||
* - SQL Server = 100%
|
||||
* non-overriding database:
|
||||
* - Firebird = 70%
|
||||
*/
|
||||
#define HEAP_MIN_FILLFACTOR 50
|
||||
#define HEAP_DEFAULT_FILLFACTOR 100
|
||||
|
||||
int fillfactor;
|
||||
HeapOption *result;
|
||||
|
||||
DefElem kwds[] =
|
||||
{
|
||||
{ T_DefElem, "fillfactor" },
|
||||
};
|
||||
|
||||
/*
|
||||
* parse options
|
||||
*/
|
||||
OptionParse(options, lengthof(kwds), kwds, true);
|
||||
|
||||
/* 0: fillfactor */
|
||||
if (kwds[0].arg)
|
||||
fillfactor = (int) defGetInt64(&kwds[0]);
|
||||
else
|
||||
fillfactor = HEAP_DEFAULT_FILLFACTOR;
|
||||
if (fillfactor < HEAP_MIN_FILLFACTOR || 100 < fillfactor)
|
||||
{
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("fillfactor=%d should be between %d and 100",
|
||||
fillfactor, HEAP_MIN_FILLFACTOR)));
|
||||
}
|
||||
|
||||
/*
|
||||
* build option
|
||||
*/
|
||||
result = (HeapOption *)
|
||||
MemoryContextAlloc(CacheMemoryContext, sizeof(HeapOption));
|
||||
VARATT_SIZEP(result) = sizeof(HeapOption);
|
||||
result->fillfactor = fillfactor;
|
||||
return (bytea *) result;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.61 2006/03/05 15:58:21 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.62 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -102,12 +102,18 @@ RelationGetBufferForTuple(Relation relation, Size len,
|
||||
{
|
||||
Buffer buffer = InvalidBuffer;
|
||||
Page pageHeader;
|
||||
Size pageFreeSpace;
|
||||
Size pageFreeSpace,
|
||||
freespace;
|
||||
BlockNumber targetBlock,
|
||||
otherBlock;
|
||||
bool needLock;
|
||||
|
||||
if (relation->rd_options == NULL)
|
||||
elog(ERROR, "RelationGetBufferForTuple %s IS NULL", RelationGetRelationName(relation));
|
||||
Assert(relation->rd_options != NULL);
|
||||
|
||||
len = MAXALIGN(len); /* be conservative */
|
||||
freespace = HeapGetPageFreeSpace(relation);
|
||||
|
||||
/*
|
||||
* If we're gonna fail for oversize tuple, do it right away
|
||||
@ -146,7 +152,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
|
||||
* We have no cached target page, so ask the FSM for an initial
|
||||
* target.
|
||||
*/
|
||||
targetBlock = GetPageWithFreeSpace(&relation->rd_node, len);
|
||||
targetBlock = GetPageWithFreeSpace(&relation->rd_node, len + freespace);
|
||||
|
||||
/*
|
||||
* If the FSM knows nothing of the rel, try the last page before we
|
||||
@ -202,7 +208,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
|
||||
*/
|
||||
pageHeader = (Page) BufferGetPage(buffer);
|
||||
pageFreeSpace = PageGetFreeSpace(pageHeader);
|
||||
if (len <= pageFreeSpace)
|
||||
if (len + freespace <= pageFreeSpace)
|
||||
{
|
||||
/* use this page as future insert target, too */
|
||||
relation->rd_targblock = targetBlock;
|
||||
@ -235,7 +241,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
|
||||
targetBlock = RecordAndGetPageWithFreeSpace(&relation->rd_node,
|
||||
targetBlock,
|
||||
pageFreeSpace,
|
||||
len);
|
||||
len + freespace);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.55 2006/05/07 01:21:30 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/index/genam.c,v 1.56 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* many of the old access method routines have been turned into
|
||||
@ -21,8 +21,12 @@
|
||||
|
||||
#include "access/genam.h"
|
||||
#include "access/heapam.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "pgstat.h"
|
||||
#include "utils/catcache.h"
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@ -260,3 +264,44 @@ systable_endscan(SysScanDesc sysscan)
|
||||
|
||||
pfree(sysscan);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse options for generic indexes.
|
||||
*/
|
||||
bytea *
|
||||
genam_option(ArrayType *options,
|
||||
int minFillfactor, int defaultFillfactor)
|
||||
{
|
||||
int fillfactor;
|
||||
IndexOption *result;
|
||||
|
||||
DefElem kwds[] =
|
||||
{
|
||||
{ T_DefElem, "fillfactor" },
|
||||
};
|
||||
|
||||
/*
|
||||
* parse options
|
||||
*/
|
||||
OptionParse(options, lengthof(kwds), kwds, true);
|
||||
|
||||
/* 0: fillfactor */
|
||||
if (kwds[0].arg)
|
||||
fillfactor = (int) defGetInt64(&kwds[0]);
|
||||
else
|
||||
fillfactor = defaultFillfactor;
|
||||
if (fillfactor < minFillfactor || 100 < fillfactor)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("fillfactor=%d should be between %d and 100",
|
||||
fillfactor, minFillfactor)));
|
||||
|
||||
/*
|
||||
* build options
|
||||
*/
|
||||
result = (IndexOption *)
|
||||
MemoryContextAlloc(CacheMemoryContext, sizeof(IndexOption));
|
||||
VARATT_SIZEP(result) = sizeof(IndexOption);
|
||||
result->fillfactor = fillfactor;
|
||||
return (bytea *) result;
|
||||
}
|
||||
|
@ -8,13 +8,14 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.137 2006/05/08 00:00:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.138 2006/07/02 02:23:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/genam.h"
|
||||
#include "access/heapam.h"
|
||||
#include "access/nbtree.h"
|
||||
#include "miscadmin.h"
|
||||
@ -25,6 +26,7 @@ typedef struct
|
||||
{
|
||||
/* context data for _bt_checksplitloc */
|
||||
Size newitemsz; /* size of new item to be inserted */
|
||||
int fillfactor; /* used when insert at right most */
|
||||
bool is_leaf; /* T if splitting a leaf page */
|
||||
bool is_rightmost; /* T if splitting a rightmost page */
|
||||
|
||||
@ -986,14 +988,11 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
|
||||
* it needs to go into!)
|
||||
*
|
||||
* If the page is the rightmost page on its level, we instead try to arrange
|
||||
* for twice as much free space on the right as on the left. In this way,
|
||||
* for reserving (100-fillfactor)% of free space on left page. In this way,
|
||||
* when we are inserting successively increasing keys (consider sequences,
|
||||
* timestamps, etc) we will end up with a tree whose pages are about 67% full,
|
||||
* timestamps, etc) we will end up with a tree whose pages are about fillfactor% full,
|
||||
* instead of the 50% full result that we'd get without this special case.
|
||||
* (We could bias it even further to make the initially-loaded tree more full.
|
||||
* But since the steady-state load for a btree is about 70%, we'd likely just
|
||||
* be making more page-splitting work for ourselves later on, when we start
|
||||
* seeing updates to existing tuples.)
|
||||
* This is the same as initially-loaded tree.
|
||||
*
|
||||
* We are passed the intended insert position of the new tuple, expressed as
|
||||
* the offsetnumber of the tuple it must go in front of. (This could be
|
||||
@ -1027,6 +1026,7 @@ _bt_findsplitloc(Relation rel,
|
||||
/* Passed-in newitemsz is MAXALIGNED but does not include line pointer */
|
||||
newitemsz += sizeof(ItemIdData);
|
||||
state.newitemsz = newitemsz;
|
||||
state.fillfactor = IndexGetFillFactor(rel);
|
||||
state.is_leaf = P_ISLEAF(opaque);
|
||||
state.is_rightmost = P_RIGHTMOST(opaque);
|
||||
state.have_split = false;
|
||||
@ -1157,10 +1157,11 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
|
||||
if (state->is_rightmost)
|
||||
{
|
||||
/*
|
||||
* On a rightmost page, try to equalize right free space with
|
||||
* twice the left free space. See comments for _bt_findsplitloc.
|
||||
* On a rightmost page, try to reserve (100-fillfactor)% of
|
||||
* free space on left page. See comments for _bt_findsplitloc.
|
||||
*/
|
||||
delta = (2 * leftfree) - rightfree;
|
||||
delta = (state->fillfactor * leftfree)
|
||||
- ((100 - state->fillfactor) * rightfree);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -56,13 +56,14 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.102 2006/06/27 16:53:02 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.103 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/genam.h"
|
||||
#include "access/nbtree.h"
|
||||
#include "access/xlog.h"
|
||||
#include "miscadmin.h"
|
||||
@ -120,6 +121,7 @@ typedef struct BTWriteState
|
||||
|
||||
|
||||
static Page _bt_blnewpage(uint32 level);
|
||||
static Size _bt_full_threshold(Relation index, Size pagesize, bool leaf);
|
||||
static BTPageState *_bt_pagestate(BTWriteState *wstate, uint32 level);
|
||||
static void _bt_slideleft(Page page);
|
||||
static void _bt_sortaddtup(Page page, Size itemsize,
|
||||
@ -327,6 +329,22 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
|
||||
pfree(page);
|
||||
}
|
||||
|
||||
/*
|
||||
* The steady-state load factor for btrees is usually estimated at 70%.
|
||||
* We choose to pack leaf pages to 90% and upper pages to 70% as defaults.
|
||||
*/
|
||||
static Size
|
||||
_bt_full_threshold(Relation index, Size pagesize, bool leaf)
|
||||
{
|
||||
int fillfactor = IndexGetFillFactor(index);
|
||||
if (!leaf)
|
||||
{
|
||||
/* XXX: Is this reasonable? */
|
||||
fillfactor = Max(70, 3 * fillfactor - 200);
|
||||
}
|
||||
return pagesize * (100 - fillfactor) / 100;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate and initialize a new BTPageState. the returned structure
|
||||
* is suitable for immediate use by _bt_buildadd.
|
||||
@ -347,10 +365,8 @@ _bt_pagestate(BTWriteState *wstate, uint32 level)
|
||||
state->btps_lastoff = P_HIKEY;
|
||||
state->btps_level = level;
|
||||
/* set "full" threshold based on level. See notes at head of file. */
|
||||
if (level > 0)
|
||||
state->btps_full = (PageGetPageSize(state->btps_page) * 3) / 10;
|
||||
else
|
||||
state->btps_full = PageGetPageSize(state->btps_page) / 10;
|
||||
state->btps_full = _bt_full_threshold(wstate->index,
|
||||
PageGetPageSize(state->btps_page), level == 0);
|
||||
/* no parent level, yet */
|
||||
state->btps_next = NULL;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.74 2006/05/08 00:00:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.75 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1079,3 +1079,16 @@ BTreeShmemInit(void)
|
||||
else
|
||||
Assert(found);
|
||||
}
|
||||
|
||||
Datum
|
||||
btoption(PG_FUNCTION_ARGS)
|
||||
{
|
||||
#define BTREE_MIN_FILLFACTOR 50
|
||||
#define BTREE_DEFAULT_FILLFACTOR 90
|
||||
|
||||
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
|
||||
|
||||
/* Use index common routine. */
|
||||
PG_RETURN_BYTEA_P(genam_option(options,
|
||||
BTREE_MIN_FILLFACTOR, BTREE_DEFAULT_FILLFACTOR));
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.44 2006/04/14 20:27:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlogutils.c,v 1.45 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -337,7 +337,7 @@ _xl_remove_hash_entry(XLogRelDesc *rdesc)
|
||||
RelationCloseSmgr(&(rdesc->reldata));
|
||||
|
||||
memset(rdesc, 0, sizeof(XLogRelDesc));
|
||||
memset(tpgc, 0, sizeof(FormData_pg_class));
|
||||
memset(tpgc, 0, CLASS_TUPLE_SIZE);
|
||||
rdesc->reldata.rd_rel = tpgc;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.80 2006/03/07 01:03:12 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/bootstrap/bootparse.y,v 1.81 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -19,6 +19,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "access/attnum.h"
|
||||
#include "access/heapam.h"
|
||||
#include "access/htup.h"
|
||||
#include "access/itup.h"
|
||||
#include "access/skey.h"
|
||||
@ -192,6 +193,8 @@ Boot_CreateStmt:
|
||||
RELKIND_RELATION,
|
||||
$3,
|
||||
true);
|
||||
boot_reldesc->rd_options =
|
||||
heap_option(RELKIND_RELATION, NULL);
|
||||
elog(DEBUG4, "bootstrap relation created");
|
||||
}
|
||||
else
|
||||
@ -209,7 +212,8 @@ Boot_CreateStmt:
|
||||
true,
|
||||
0,
|
||||
ONCOMMIT_NOOP,
|
||||
true);
|
||||
true,
|
||||
NULL);
|
||||
elog(DEBUG4, "relation created with oid %u", id);
|
||||
}
|
||||
do_end();
|
||||
@ -252,7 +256,7 @@ Boot_DeclareIndexStmt:
|
||||
LexIDStr($8),
|
||||
NULL,
|
||||
$10,
|
||||
NULL, NIL,
|
||||
NULL, NIL, NIL,
|
||||
false, false, false,
|
||||
false, false, true, false);
|
||||
do_end();
|
||||
@ -270,7 +274,7 @@ Boot_DeclareUniqueIndexStmt:
|
||||
LexIDStr($9),
|
||||
NULL,
|
||||
$11,
|
||||
NULL, NIL,
|
||||
NULL, NIL, NIL,
|
||||
true, false, false,
|
||||
false, false, true, false);
|
||||
do_end();
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.302 2006/06/29 16:07:29 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.303 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -44,20 +44,24 @@
|
||||
#include "catalog/pg_type.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "miscadmin.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "optimizer/clauses.h"
|
||||
#include "optimizer/planmain.h"
|
||||
#include "optimizer/var.h"
|
||||
#include "parser/parse_coerce.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "parser/parse_relation.h"
|
||||
#include "rewrite/rewriteRemove.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/catcache.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/fmgroids.h"
|
||||
#include "utils/inval.h"
|
||||
#include "utils/lsyscache.h"
|
||||
#include "utils/memutils.h"
|
||||
#include "utils/relcache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
@ -66,7 +70,8 @@ static void AddNewRelationTuple(Relation pg_class_desc,
|
||||
Relation new_rel_desc,
|
||||
Oid new_rel_oid, Oid new_type_oid,
|
||||
Oid relowner,
|
||||
char relkind);
|
||||
char relkind,
|
||||
ArrayType *options);
|
||||
static Oid AddNewRelationType(const char *typeName,
|
||||
Oid typeNamespace,
|
||||
Oid new_rel_oid,
|
||||
@ -558,7 +563,8 @@ AddNewRelationTuple(Relation pg_class_desc,
|
||||
Oid new_rel_oid,
|
||||
Oid new_type_oid,
|
||||
Oid relowner,
|
||||
char relkind)
|
||||
char relkind,
|
||||
ArrayType *options)
|
||||
{
|
||||
Form_pg_class new_rel_reltup;
|
||||
HeapTuple tup;
|
||||
@ -596,15 +602,8 @@ AddNewRelationTuple(Relation pg_class_desc,
|
||||
|
||||
new_rel_desc->rd_att->tdtypeid = new_type_oid;
|
||||
|
||||
/* ----------------
|
||||
* now form a tuple to add to pg_class
|
||||
* XXX Natts_pg_class_fixed is a hack - see pg_class.h
|
||||
* ----------------
|
||||
*/
|
||||
tup = heap_addheader(Natts_pg_class_fixed,
|
||||
true,
|
||||
CLASS_TUPLE_SIZE,
|
||||
(void *) new_rel_reltup);
|
||||
/* now form a tuple to add to pg_class */
|
||||
tup = build_class_tuple(new_rel_reltup, options);
|
||||
|
||||
/* force tuple to have the desired OID */
|
||||
HeapTupleSetOid(tup, new_rel_oid);
|
||||
@ -661,6 +660,8 @@ AddNewRelationType(const char *typeName,
|
||||
* heap_create_with_catalog
|
||||
*
|
||||
* creates a new cataloged relation. see comments above.
|
||||
*
|
||||
* if opaque is specified, it must be allocated in CacheMemoryContext.
|
||||
* --------------------------------
|
||||
*/
|
||||
Oid
|
||||
@ -675,10 +676,12 @@ heap_create_with_catalog(const char *relname,
|
||||
bool oidislocal,
|
||||
int oidinhcount,
|
||||
OnCommitAction oncommit,
|
||||
bool allow_system_table_mods)
|
||||
bool allow_system_table_mods,
|
||||
ArrayType *options)
|
||||
{
|
||||
Relation pg_class_desc;
|
||||
Relation new_rel_desc;
|
||||
bytea *new_rel_options;
|
||||
Oid new_type_oid;
|
||||
|
||||
pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
@ -695,6 +698,13 @@ heap_create_with_catalog(const char *relname,
|
||||
(errcode(ERRCODE_DUPLICATE_TABLE),
|
||||
errmsg("relation \"%s\" already exists", relname)));
|
||||
|
||||
/*
|
||||
* Parse options to check if option is valid.
|
||||
*/
|
||||
new_rel_options = heap_option(relkind, options);
|
||||
Assert(!new_rel_options ||
|
||||
GetMemoryChunkContext(new_rel_options) == CacheMemoryContext);
|
||||
|
||||
/*
|
||||
* Allocate an OID for the relation, unless we were told what to use.
|
||||
*
|
||||
@ -718,6 +728,7 @@ heap_create_with_catalog(const char *relname,
|
||||
relkind,
|
||||
shared_relation,
|
||||
allow_system_table_mods);
|
||||
new_rel_desc->rd_options = new_rel_options;
|
||||
|
||||
Assert(relid == RelationGetRelid(new_rel_desc));
|
||||
|
||||
@ -745,7 +756,8 @@ heap_create_with_catalog(const char *relname,
|
||||
relid,
|
||||
new_type_oid,
|
||||
ownerid,
|
||||
relkind);
|
||||
relkind,
|
||||
options);
|
||||
|
||||
/*
|
||||
* now add tuples to pg_attribute for the attributes in our new relation.
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.266 2006/05/10 23:18:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.267 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*
|
||||
* INTERFACE ROUTINES
|
||||
@ -37,6 +37,7 @@
|
||||
#include "executor/executor.h"
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/clauses.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parse_expr.h"
|
||||
#include "storage/procarray.h"
|
||||
#include "storage/smgr.h"
|
||||
@ -53,7 +54,8 @@
|
||||
static TupleDesc ConstructTupleDescriptor(Relation heapRelation,
|
||||
IndexInfo *indexInfo,
|
||||
Oid *classObjectId);
|
||||
static void UpdateRelationRelation(Relation pg_class, Relation indexRelation);
|
||||
static void UpdateRelationRelation(Relation pg_class, Relation indexRelation,
|
||||
ArrayType *options);
|
||||
static void InitializeAttributeOids(Relation indexRelation,
|
||||
int numatts, Oid indexoid);
|
||||
static void AppendAttributeTuples(Relation indexRelation, int numatts);
|
||||
@ -241,15 +243,12 @@ ConstructTupleDescriptor(Relation heapRelation,
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
UpdateRelationRelation(Relation pg_class, Relation indexRelation)
|
||||
UpdateRelationRelation(Relation pg_class, Relation indexRelation,
|
||||
ArrayType *options)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
|
||||
/* XXX Natts_pg_class_fixed is a hack - see pg_class.h */
|
||||
tuple = heap_addheader(Natts_pg_class_fixed,
|
||||
true,
|
||||
CLASS_TUPLE_SIZE,
|
||||
(void *) indexRelation->rd_rel);
|
||||
tuple = build_class_tuple(indexRelation->rd_rel, options);
|
||||
|
||||
/*
|
||||
* the new tuple must have the oid already chosen for the index. sure
|
||||
@ -467,6 +466,7 @@ index_create(Oid heapRelationId,
|
||||
Oid accessMethodObjectId,
|
||||
Oid tableSpaceId,
|
||||
Oid *classObjectId,
|
||||
List *options,
|
||||
bool isprimary,
|
||||
bool istoast,
|
||||
bool isconstraint,
|
||||
@ -481,6 +481,9 @@ index_create(Oid heapRelationId,
|
||||
Oid namespaceId;
|
||||
int i;
|
||||
|
||||
ArrayType *array;
|
||||
RegProcedure amoption;
|
||||
|
||||
pg_class = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
@ -578,12 +581,41 @@ index_create(Oid heapRelationId,
|
||||
indexRelation->rd_rel->relkind = RELKIND_INDEX;
|
||||
indexRelation->rd_rel->relhasoids = false;
|
||||
|
||||
/*
|
||||
* AM specific options.
|
||||
*/
|
||||
array = OptionBuild(NULL, options);
|
||||
if (indexRelation->rd_am)
|
||||
{
|
||||
amoption = indexRelation->rd_am->amoption;
|
||||
}
|
||||
else
|
||||
{
|
||||
HeapTuple tuple;
|
||||
|
||||
/*
|
||||
* We may use the access method before initializing relation,
|
||||
* so we pick up AM from syscache directly.
|
||||
*/
|
||||
tuple = SearchSysCache(AMOID,
|
||||
ObjectIdGetDatum(accessMethodObjectId),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "cache lookup failed for access method %u",
|
||||
accessMethodObjectId);
|
||||
amoption = ((Form_pg_am) GETSTRUCT(tuple))->amoption;
|
||||
ReleaseSysCache(tuple);
|
||||
}
|
||||
indexRelation->rd_options = index_option(amoption, array);
|
||||
|
||||
/*
|
||||
* store index's pg_class entry
|
||||
*/
|
||||
UpdateRelationRelation(pg_class, indexRelation);
|
||||
UpdateRelationRelation(pg_class, indexRelation, array);
|
||||
|
||||
/* done with pg_class */
|
||||
if (array)
|
||||
pfree(array);
|
||||
heap_close(pg_class, RowExclusiveLock);
|
||||
|
||||
/*
|
||||
@ -1751,3 +1783,23 @@ reindex_relation(Oid relid, bool toast_too)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse options for indexes.
|
||||
*
|
||||
* amoption Oid of option parser.
|
||||
* options Options as text[]
|
||||
*/
|
||||
bytea *index_option(RegProcedure amoption, ArrayType *options)
|
||||
{
|
||||
Datum datum;
|
||||
|
||||
Assert(RegProcedureIsValid(amoption));
|
||||
|
||||
datum = OidFunctionCall1(amoption, PointerGetDatum(options));
|
||||
|
||||
if (DatumGetPointer(datum) == NULL)
|
||||
return NULL;
|
||||
|
||||
return DatumGetByteaP(datum);
|
||||
}
|
||||
|
@ -9,16 +9,19 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/indexing.c,v 1.111 2006/03/05 15:58:22 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/catalog/indexing.c,v 1.112 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "access/genam.h"
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "executor/executor.h"
|
||||
#include "utils/syscache.h"
|
||||
#include "commands/defrem.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.147 2006/05/02 22:25:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/cluster.c,v 1.148 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -566,6 +566,8 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
|
||||
tupdesc;
|
||||
Oid OIDNewHeap;
|
||||
Relation OldHeap;
|
||||
HeapTuple tuple;
|
||||
ArrayType *options;
|
||||
|
||||
OldHeap = heap_open(OIDOldHeap, AccessExclusiveLock);
|
||||
OldHeapDesc = RelationGetDescr(OldHeap);
|
||||
@ -576,6 +578,26 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
|
||||
*/
|
||||
tupdesc = CreateTupleDescCopyConstr(OldHeapDesc);
|
||||
|
||||
/*
|
||||
* Use options of the old heap for new heap.
|
||||
*/
|
||||
tuple = SearchSysCache(RELOID,
|
||||
ObjectIdGetDatum(OIDOldHeap),
|
||||
0, 0, 0);
|
||||
if (tuple)
|
||||
{
|
||||
Datum datum;
|
||||
bool isNull;
|
||||
datum = SysCacheGetAttr(RELOID, tuple,
|
||||
Anum_pg_class_reloptions, &isNull);
|
||||
options = isNull ? NULL : DatumGetArrayTypeP(datum);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* should not happen */
|
||||
options = NULL;
|
||||
}
|
||||
|
||||
OIDNewHeap = heap_create_with_catalog(NewName,
|
||||
RelationGetNamespace(OldHeap),
|
||||
NewTableSpace,
|
||||
@ -587,7 +609,10 @@ make_new_heap(Oid OIDOldHeap, const char *NewName, Oid NewTableSpace)
|
||||
true,
|
||||
0,
|
||||
ONCOMMIT_NOOP,
|
||||
allowSystemTableMods);
|
||||
allowSystemTableMods,
|
||||
options);
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
/*
|
||||
* Advance command counter so that the newly-created relation's catalog
|
||||
|
@ -9,7 +9,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.95 2006/03/14 22:48:18 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/define.c,v 1.96 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@ -110,6 +110,7 @@ defGetNumeric(DefElem *def)
|
||||
case T_Integer:
|
||||
return (double) intVal(def->arg);
|
||||
case T_Float:
|
||||
case T_String: /* XXX: needs strict check? */
|
||||
return floatVal(def->arg);
|
||||
default:
|
||||
ereport(ERROR,
|
||||
@ -127,14 +128,30 @@ bool
|
||||
defGetBoolean(DefElem *def)
|
||||
{
|
||||
/*
|
||||
* Presently, boolean flags must simply be present or absent. Later we
|
||||
* could allow 'flag = t', 'flag = f', etc.
|
||||
* Presently, boolean flags must simply be present/absent or
|
||||
* integer 0/1. Later we could allow 'flag = t', 'flag = f', etc.
|
||||
*/
|
||||
if (def->arg == NULL)
|
||||
return true;
|
||||
switch (nodeTag(def->arg))
|
||||
{
|
||||
case T_Integer:
|
||||
switch (intVal(def->arg))
|
||||
{
|
||||
case 0:
|
||||
return false;
|
||||
case 1:
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* on error */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("%s does not take a parameter",
|
||||
errmsg("%s requires a boolean value",
|
||||
def->defname)));
|
||||
return false; /* keep compiler quiet */
|
||||
}
|
||||
@ -155,7 +172,7 @@ defGetInt64(DefElem *def)
|
||||
case T_Integer:
|
||||
return (int64) intVal(def->arg);
|
||||
case T_Float:
|
||||
|
||||
case T_String: /* XXX: needs strict check? */
|
||||
/*
|
||||
* Values too large for int4 will be represented as Float
|
||||
* constants by the lexer. Accept these if they are valid int8
|
||||
@ -275,3 +292,12 @@ defGetTypeLength(DefElem *def)
|
||||
def->defname, defGetString(def))));
|
||||
return 0; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
DefElem *
|
||||
defWithOids(bool value)
|
||||
{
|
||||
DefElem *f = makeNode(DefElem);
|
||||
f->defname = "oids";
|
||||
f->arg = (Node *)makeInteger(value);
|
||||
return f;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.141 2006/06/07 17:20:17 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.142 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -77,6 +77,7 @@ static bool relationHasPrimaryKey(Relation rel);
|
||||
* 'isconstraint': index is for a PRIMARY KEY or UNIQUE constraint,
|
||||
* so build a pg_constraint entry for it.
|
||||
* 'is_alter_table': this is due to an ALTER rather than a CREATE operation.
|
||||
* 'options': options passed by WITH.
|
||||
* 'check_rights': check for CREATE rights in the namespace. (This should
|
||||
* be true except when ALTER is deleting/recreating an index.)
|
||||
* 'skip_build': make the catalog entries but leave the index file empty;
|
||||
@ -92,6 +93,7 @@ DefineIndex(RangeVar *heapRelation,
|
||||
List *attributeList,
|
||||
Expr *predicate,
|
||||
List *rangetable,
|
||||
List *options,
|
||||
bool unique,
|
||||
bool primary,
|
||||
bool isconstraint,
|
||||
@ -397,7 +399,7 @@ DefineIndex(RangeVar *heapRelation,
|
||||
|
||||
index_create(relationId, indexRelationName, indexRelationId,
|
||||
indexInfo, accessMethodId, tablespaceId, classObjectId,
|
||||
primary, false, isconstraint,
|
||||
options, primary, false, isconstraint,
|
||||
allowSystemTableMods, skip_build);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Copyright (c) 2002-2006, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.53 2006/06/20 22:51:59 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/prepare.c,v 1.54 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -196,6 +196,7 @@ ExecuteQuery(ExecuteStmt *stmt, ParamListInfo params,
|
||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||
errmsg("prepared statement is not a SELECT")));
|
||||
query->into = copyObject(stmt->into);
|
||||
query->intoOptions = copyObject(stmt->intoOptions);
|
||||
query->intoHasOids = stmt->into_has_oids;
|
||||
query->intoOnCommit = stmt->into_on_commit;
|
||||
if (stmt->into_tbl_space)
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.132 2006/03/31 23:32:06 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/sequence.c,v 1.133 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -180,7 +180,7 @@ DefineSequence(CreateSeqStmt *seq)
|
||||
stmt->relation = seq->sequence;
|
||||
stmt->inhRelations = NIL;
|
||||
stmt->constraints = NIL;
|
||||
stmt->hasoids = MUST_NOT_HAVE_OIDS;
|
||||
stmt->options = list_make1(defWithOids(false));
|
||||
stmt->oncommit = ONCOMMIT_NOOP;
|
||||
stmt->tablespacename = NULL;
|
||||
|
||||
@ -205,7 +205,17 @@ DefineSequence(CreateSeqStmt *seq)
|
||||
|
||||
/* Now form & insert sequence tuple */
|
||||
tuple = heap_formtuple(tupDesc, value, null);
|
||||
simple_heap_insert(rel, tuple);
|
||||
|
||||
{
|
||||
/*
|
||||
* HACK: Sequences insert only one tuple during initialize.
|
||||
* We treat sequences as heaps then.
|
||||
*/
|
||||
HeapOption opaque = { sizeof(HeapOption), 100 };
|
||||
rel->rd_options = (bytea *) &opaque;
|
||||
simple_heap_insert(rel, tuple);
|
||||
rel->rd_options = NULL;
|
||||
}
|
||||
|
||||
Assert(ItemPointerGetOffsetNumber(&(tuple->t_self)) == FirstOffsetNumber);
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.189 2006/07/02 01:58:36 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.190 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -62,7 +62,6 @@
|
||||
#include "utils/relcache.h"
|
||||
#include "utils/syscache.h"
|
||||
|
||||
|
||||
/*
|
||||
* ON COMMIT action list
|
||||
*/
|
||||
@ -196,6 +195,7 @@ static void ATRewriteTables(List **wqueue);
|
||||
static void ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap);
|
||||
static AlteredTableInfo *ATGetQueueEntry(List **wqueue, Relation rel);
|
||||
static void ATSimplePermissions(Relation rel, bool allowView);
|
||||
static void ATSimplePermissionsRelationOrIndex(Relation rel);
|
||||
static void ATSimpleRecursion(List **wqueue, Relation rel,
|
||||
AlterTableCmd *cmd, bool recurse);
|
||||
static void ATOneLevelRecursion(List **wqueue, Relation rel,
|
||||
@ -248,6 +248,7 @@ static void ATExecDropCluster(Relation rel);
|
||||
static void ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel,
|
||||
char *tablespacename);
|
||||
static void ATExecSetTableSpace(Oid tableOid, Oid newTableSpace);
|
||||
static void ATExecSetOptions(Relation rel, List *newOptions);
|
||||
static void ATExecEnableDisableTrigger(Relation rel, char *trigname,
|
||||
bool enable, bool skip_system);
|
||||
static void ATExecAddInherits(Relation rel, RangeVar *parent);
|
||||
@ -285,6 +286,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
ListCell *listptr;
|
||||
int i;
|
||||
AttrNumber attnum;
|
||||
ArrayType *options;
|
||||
|
||||
/*
|
||||
* Truncate relname to appropriate length (probably a waste of time, as
|
||||
@ -366,7 +368,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
*/
|
||||
descriptor = BuildDescForRelation(schema);
|
||||
|
||||
localHasOids = interpretOidsOption(stmt->hasoids);
|
||||
localHasOids = interpretOidsOption(stmt->options);
|
||||
descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
|
||||
|
||||
if (old_constraints != NIL)
|
||||
@ -426,6 +428,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
}
|
||||
}
|
||||
|
||||
options = OptionBuild(NULL, stmt->options);
|
||||
relationId = heap_create_with_catalog(relname,
|
||||
namespaceId,
|
||||
tablespaceId,
|
||||
@ -437,7 +440,10 @@ DefineRelation(CreateStmt *stmt, char relkind)
|
||||
localHasOids,
|
||||
parentOidCount,
|
||||
stmt->oncommit,
|
||||
allowSystemTableMods);
|
||||
allowSystemTableMods,
|
||||
options);
|
||||
if (options)
|
||||
pfree(options);
|
||||
|
||||
StoreCatalogInheritance(relationId, inheritOids);
|
||||
|
||||
@ -2092,10 +2098,17 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
|
||||
pass = AT_PASS_DROP;
|
||||
break;
|
||||
case AT_SetTableSpace: /* SET TABLESPACE */
|
||||
ATSimplePermissionsRelationOrIndex(rel);
|
||||
/* This command never recurses */
|
||||
ATPrepSetTableSpace(tab, rel, cmd->name);
|
||||
pass = AT_PASS_MISC; /* doesn't actually matter */
|
||||
break;
|
||||
case AT_SetOptions: /* SET (...) */
|
||||
ATSimplePermissionsRelationOrIndex(rel);
|
||||
/* This command never recurses */
|
||||
/* No command-specific prep needed */
|
||||
pass = AT_PASS_MISC;
|
||||
break;
|
||||
case AT_EnableTrig: /* ENABLE TRIGGER variants */
|
||||
case AT_EnableTrigAll:
|
||||
case AT_EnableTrigUser:
|
||||
@ -2266,6 +2279,9 @@ ATExecCmd(AlteredTableInfo *tab, Relation rel, AlterTableCmd *cmd)
|
||||
* Nothing to do here; Phase 3 does the work
|
||||
*/
|
||||
break;
|
||||
case AT_SetOptions: /* SET (...) */
|
||||
ATExecSetOptions(rel, (List *) cmd->def);
|
||||
break;
|
||||
case AT_EnableTrig: /* ENABLE TRIGGER name */
|
||||
ATExecEnableDisableTrigger(rel, cmd->name, true, false);
|
||||
break;
|
||||
@ -2776,6 +2792,35 @@ ATSimplePermissions(Relation rel, bool allowView)
|
||||
RelationGetRelationName(rel))));
|
||||
}
|
||||
|
||||
/*
|
||||
* ATSimplePermissionsRelationOrIndex
|
||||
*
|
||||
* - Ensure that it is a relation or an index
|
||||
* - Ensure this user is the owner
|
||||
* - Ensure that it is not a system table
|
||||
*/
|
||||
static void
|
||||
ATSimplePermissionsRelationOrIndex(Relation rel)
|
||||
{
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION &&
|
||||
rel->rd_rel->relkind != RELKIND_INDEX)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||
errmsg("\"%s\" is not a table or index",
|
||||
RelationGetRelationName(rel))));
|
||||
|
||||
/* Permissions checks */
|
||||
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelation(rel))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied: \"%s\" is a system catalog",
|
||||
RelationGetRelationName(rel))));
|
||||
}
|
||||
|
||||
/*
|
||||
* ATSimpleRecursion
|
||||
*
|
||||
@ -3804,6 +3849,7 @@ ATExecAddIndex(AlteredTableInfo *tab, Relation rel,
|
||||
stmt->indexParams, /* parameters */
|
||||
(Expr *) stmt->whereClause,
|
||||
stmt->rangetable,
|
||||
stmt->options,
|
||||
stmt->unique,
|
||||
stmt->primary,
|
||||
stmt->isconstraint,
|
||||
@ -5690,28 +5736,6 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
|
||||
Oid tablespaceId;
|
||||
AclResult aclresult;
|
||||
|
||||
/*
|
||||
* We do our own permission checking because we want to allow this on
|
||||
* indexes.
|
||||
*/
|
||||
if (rel->rd_rel->relkind != RELKIND_RELATION &&
|
||||
rel->rd_rel->relkind != RELKIND_INDEX)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||
errmsg("\"%s\" is not a table or index",
|
||||
RelationGetRelationName(rel))));
|
||||
|
||||
/* Permissions checks */
|
||||
if (!pg_class_ownercheck(RelationGetRelid(rel), GetUserId()))
|
||||
aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
|
||||
RelationGetRelationName(rel));
|
||||
|
||||
if (!allowSystemTableMods && IsSystemRelation(rel))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied: \"%s\" is a system catalog",
|
||||
RelationGetRelationName(rel))));
|
||||
|
||||
/* Check that the tablespace exists */
|
||||
tablespaceId = get_tablespace_oid(tablespacename);
|
||||
if (!OidIsValid(tablespaceId))
|
||||
@ -5732,6 +5756,89 @@ ATPrepSetTableSpace(AlteredTableInfo *tab, Relation rel, char *tablespacename)
|
||||
tab->newTableSpace = tablespaceId;
|
||||
}
|
||||
|
||||
/*
|
||||
* ALTER TABLE/INDEX SET (...)
|
||||
*/
|
||||
static void
|
||||
ATExecSetOptions(Relation rel, List *newOptions)
|
||||
{
|
||||
Oid relid;
|
||||
Relation pgclass;
|
||||
HeapTuple tuple;
|
||||
Datum datum;
|
||||
bool isnull;
|
||||
ArrayType *mergedOptions;
|
||||
bytea *options;
|
||||
|
||||
if (list_length(newOptions) == 0)
|
||||
return; /* do nothing */
|
||||
|
||||
relid = RelationGetRelid(rel);
|
||||
pgclass = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
tuple = SearchSysCache(RELOID,
|
||||
ObjectIdGetDatum(relid),
|
||||
0, 0, 0);
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "cache lookup failed for relation %u", relid);
|
||||
|
||||
datum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_reloptions, &isnull);
|
||||
|
||||
mergedOptions = OptionBuild(
|
||||
isnull ? NULL : DatumGetArrayTypeP(datum), newOptions);
|
||||
|
||||
switch (rel->rd_rel->relkind)
|
||||
{
|
||||
case RELKIND_RELATION:
|
||||
case RELKIND_TOASTVALUE:
|
||||
options = heap_option(rel->rd_rel->relkind, mergedOptions);
|
||||
break;
|
||||
case RELKIND_INDEX:
|
||||
options = index_option(rel->rd_am->amoption, mergedOptions);
|
||||
break;
|
||||
default:
|
||||
elog(ERROR, "unexpected RELKIND=%c", rel->rd_rel->relkind);
|
||||
options = NULL; /* keep compiler quiet */
|
||||
break;
|
||||
}
|
||||
|
||||
if (rel->rd_options != options)
|
||||
{
|
||||
HeapTuple newtuple;
|
||||
Datum repl_val[Natts_pg_class];
|
||||
char repl_null[Natts_pg_class];
|
||||
char repl_repl[Natts_pg_class];
|
||||
|
||||
/* XXX: This is not necessarily required. */
|
||||
if (rel->rd_options)
|
||||
pfree(rel->rd_options);
|
||||
rel->rd_options = options;
|
||||
|
||||
memset(repl_repl, ' ', sizeof(repl_repl));
|
||||
memset(repl_null, ' ', sizeof(repl_null));
|
||||
repl_repl[Anum_pg_class_reloptions - 1] = 'r';
|
||||
|
||||
if (mergedOptions)
|
||||
repl_val[Anum_pg_class_reloptions - 1] =
|
||||
PointerGetDatum(mergedOptions);
|
||||
else
|
||||
repl_null[Anum_pg_class_reloptions - 1] = 'n';
|
||||
|
||||
newtuple = heap_modifytuple(tuple, RelationGetDescr(pgclass),
|
||||
repl_val, repl_null, repl_repl);
|
||||
|
||||
simple_heap_update(pgclass, &newtuple->t_self, newtuple);
|
||||
CatalogUpdateIndexes(pgclass, newtuple);
|
||||
|
||||
heap_freetuple(newtuple);
|
||||
}
|
||||
|
||||
if (mergedOptions)
|
||||
pfree(mergedOptions);
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
heap_close(pgclass, RowExclusiveLock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute ALTER TABLE SET TABLESPACE for cases where there is no tuple
|
||||
* rewriting to be done, so we just want to copy the data as fast as possible.
|
||||
@ -6553,7 +6660,8 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||
true,
|
||||
0,
|
||||
ONCOMMIT_NOOP,
|
||||
true);
|
||||
true,
|
||||
NULL);
|
||||
|
||||
/* make the toast relation visible, else index creation will fail */
|
||||
CommandCounterIncrement();
|
||||
@ -6587,7 +6695,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
|
||||
indexInfo,
|
||||
BTREE_AM_OID,
|
||||
rel->rd_rel->reltablespace,
|
||||
classObjectId,
|
||||
classObjectId, NIL,
|
||||
true, true, false, true, false);
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.91 2006/06/21 18:09:53 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.92 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
* DESCRIPTION
|
||||
* The "DefineFoo" routines take the parse tree and pick out the
|
||||
@ -1130,7 +1130,7 @@ DefineCompositeType(const RangeVar *typevar, List *coldeflist)
|
||||
createStmt->tableElts = coldeflist;
|
||||
createStmt->inhRelations = NIL;
|
||||
createStmt->constraints = NIL;
|
||||
createStmt->hasoids = MUST_NOT_HAVE_OIDS;
|
||||
createStmt->options = list_make1(defWithOids(false));
|
||||
createStmt->oncommit = ONCOMMIT_NOOP;
|
||||
createStmt->tablespacename = NULL;
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.330 2006/05/10 23:18:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/vacuum.c,v 1.331 2006/07/02 02:23:19 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -242,6 +242,7 @@ static int vac_cmp_blk(const void *left, const void *right);
|
||||
static int vac_cmp_offno(const void *left, const void *right);
|
||||
static int vac_cmp_vtlinks(const void *left, const void *right);
|
||||
static bool enough_space(VacPage vacpage, Size len);
|
||||
static Size PageGetFreeSpaceWithFillFactor(Relation relation, Page page);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
@ -1282,7 +1283,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
|
||||
relname, blkno)));
|
||||
PageInit(page, BufferGetPageSize(buf), 0);
|
||||
MarkBufferDirty(buf);
|
||||
vacpage->free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
|
||||
vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, page);
|
||||
free_space += vacpage->free;
|
||||
empty_pages++;
|
||||
empty_end_pages++;
|
||||
@ -1297,7 +1298,7 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
|
||||
{
|
||||
VacPage vacpagecopy;
|
||||
|
||||
vacpage->free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
|
||||
vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, page);
|
||||
free_space += vacpage->free;
|
||||
empty_pages++;
|
||||
empty_end_pages++;
|
||||
@ -1465,14 +1466,14 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
|
||||
{
|
||||
/* Some tuples are removable; figure free space after removal */
|
||||
PageRepairFragmentation(tempPage, NULL);
|
||||
vacpage->free = ((PageHeader) tempPage)->pd_upper - ((PageHeader) tempPage)->pd_lower;
|
||||
vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, tempPage);
|
||||
pfree(tempPage);
|
||||
do_reap = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just use current available space */
|
||||
vacpage->free = ((PageHeader) page)->pd_upper - ((PageHeader) page)->pd_lower;
|
||||
vacpage->free = PageGetFreeSpaceWithFillFactor(onerel, page);
|
||||
/* Need to reap the page if it has ~LP_USED line pointers */
|
||||
do_reap = (vacpage->offsets_free > 0);
|
||||
}
|
||||
@ -2709,8 +2710,7 @@ move_plain_tuple(Relation rel,
|
||||
|
||||
END_CRIT_SECTION();
|
||||
|
||||
dst_vacpage->free = ((PageHeader) dst_page)->pd_upper -
|
||||
((PageHeader) dst_page)->pd_lower;
|
||||
dst_vacpage->free = PageGetFreeSpaceWithFillFactor(rel, dst_page);
|
||||
LockBuffer(dst_buf, BUFFER_LOCK_UNLOCK);
|
||||
LockBuffer(old_buf, BUFFER_LOCK_UNLOCK);
|
||||
|
||||
@ -3119,6 +3119,8 @@ vac_update_fsm(Relation onerel, VacPageList fraged_pages,
|
||||
* vacuumlazy.c does, we'd be skewing that statistic.
|
||||
*/
|
||||
threshold = GetAvgFSMRequestSize(&onerel->rd_node);
|
||||
if (threshold < HeapGetPageFreeSpace(onerel))
|
||||
threshold = HeapGetPageFreeSpace(onerel);
|
||||
|
||||
pageSpaces = (PageFreeSpaceInfo *)
|
||||
palloc(nPages * sizeof(PageFreeSpaceInfo));
|
||||
@ -3385,6 +3387,18 @@ enough_space(VacPage vacpage, Size len)
|
||||
return false;
|
||||
}
|
||||
|
||||
static Size
|
||||
PageGetFreeSpaceWithFillFactor(Relation relation, Page page)
|
||||
{
|
||||
PageHeader pd = (PageHeader) page;
|
||||
Size pagefree = HeapGetPageFreeSpace(relation);
|
||||
Size freespace = pd->pd_upper - pd->pd_lower;
|
||||
|
||||
if (freespace > pagefree)
|
||||
return freespace - pagefree;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* vacuum_delay_point --- check for interrupts and cost-based delay.
|
||||
|
@ -31,7 +31,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.70 2006/05/02 22:25:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/vacuumlazy.c,v 1.71 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -149,6 +149,8 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt)
|
||||
/* Set threshold for interesting free space = average request size */
|
||||
/* XXX should we scale it up or down? Adjust vacuum.c too, if so */
|
||||
vacrelstats->threshold = GetAvgFSMRequestSize(&onerel->rd_node);
|
||||
if (vacrelstats->threshold < HeapGetPageFreeSpace(onerel))
|
||||
vacrelstats->threshold = HeapGetPageFreeSpace(onerel);
|
||||
|
||||
/* Open all indexes of the relation */
|
||||
vac_open_indexes(onerel, ShareUpdateExclusiveLock, &nindexes, &Irel);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.94 2006/03/14 22:48:18 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.95 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -17,6 +17,7 @@
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "commands/tablecmds.h"
|
||||
#include "commands/view.h"
|
||||
#include "miscadmin.h"
|
||||
@ -195,7 +196,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace)
|
||||
createStmt->tableElts = attrList;
|
||||
createStmt->inhRelations = NIL;
|
||||
createStmt->constraints = NIL;
|
||||
createStmt->hasoids = MUST_NOT_HAVE_OIDS;
|
||||
createStmt->options = list_make1(defWithOids(false));
|
||||
createStmt->oncommit = ONCOMMIT_NOOP;
|
||||
createStmt->tablespacename = NULL;
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.271 2006/06/16 18:42:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.272 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -45,6 +45,7 @@
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/clauses.h"
|
||||
#include "optimizer/var.h"
|
||||
#include "parser/parse_clause.h"
|
||||
#include "parser/parsetree.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/acl.h"
|
||||
@ -729,6 +730,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
AclResult aclresult;
|
||||
Oid intoRelationId;
|
||||
TupleDesc tupdesc;
|
||||
ArrayType *options;
|
||||
|
||||
/*
|
||||
* Check consistency of arguments
|
||||
@ -786,6 +788,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
*/
|
||||
tupdesc = CreateTupleDescCopy(tupType);
|
||||
|
||||
options = OptionBuild(NULL, parseTree->intoOptions);
|
||||
intoRelationId = heap_create_with_catalog(intoName,
|
||||
namespaceId,
|
||||
tablespaceId,
|
||||
@ -797,7 +800,10 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
||||
true,
|
||||
0,
|
||||
parseTree->intoOnCommit,
|
||||
allowSystemTableMods);
|
||||
allowSystemTableMods,
|
||||
options);
|
||||
if (options)
|
||||
pfree(options);
|
||||
|
||||
FreeTupleDesc(tupdesc);
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.339 2006/07/02 01:58:36 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.340 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -1640,6 +1640,7 @@ _copyConstraint(Constraint *from)
|
||||
COPY_NODE_FIELD(raw_expr);
|
||||
COPY_STRING_FIELD(cooked_expr);
|
||||
COPY_NODE_FIELD(keys);
|
||||
COPY_NODE_FIELD(options);
|
||||
COPY_STRING_FIELD(indexspace);
|
||||
|
||||
return newnode;
|
||||
@ -1680,6 +1681,7 @@ _copyQuery(Query *from)
|
||||
COPY_SCALAR_FIELD(resultRelation);
|
||||
COPY_NODE_FIELD(into);
|
||||
COPY_SCALAR_FIELD(intoHasOids);
|
||||
COPY_NODE_FIELD(intoOptions);
|
||||
COPY_SCALAR_FIELD(intoOnCommit);
|
||||
COPY_STRING_FIELD(intoTableSpaceName);
|
||||
COPY_SCALAR_FIELD(hasAggs);
|
||||
@ -1746,7 +1748,7 @@ _copySelectStmt(SelectStmt *from)
|
||||
COPY_NODE_FIELD(distinctClause);
|
||||
COPY_NODE_FIELD(into);
|
||||
COPY_NODE_FIELD(intoColNames);
|
||||
COPY_SCALAR_FIELD(intoHasOids);
|
||||
COPY_NODE_FIELD(intoOptions);
|
||||
COPY_SCALAR_FIELD(intoOnCommit);
|
||||
COPY_STRING_FIELD(intoTableSpaceName);
|
||||
COPY_NODE_FIELD(targetList);
|
||||
@ -1929,7 +1931,7 @@ _copyCreateStmt(CreateStmt *from)
|
||||
COPY_NODE_FIELD(tableElts);
|
||||
COPY_NODE_FIELD(inhRelations);
|
||||
COPY_NODE_FIELD(constraints);
|
||||
COPY_SCALAR_FIELD(hasoids);
|
||||
COPY_NODE_FIELD(options);
|
||||
COPY_SCALAR_FIELD(oncommit);
|
||||
COPY_STRING_FIELD(tablespacename);
|
||||
|
||||
@ -2021,6 +2023,7 @@ _copyIndexStmt(IndexStmt *from)
|
||||
COPY_STRING_FIELD(accessMethod);
|
||||
COPY_STRING_FIELD(tableSpace);
|
||||
COPY_NODE_FIELD(indexParams);
|
||||
COPY_NODE_FIELD(options);
|
||||
COPY_NODE_FIELD(whereClause);
|
||||
COPY_NODE_FIELD(rangetable);
|
||||
COPY_SCALAR_FIELD(unique);
|
||||
@ -2638,8 +2641,8 @@ _copyExecuteStmt(ExecuteStmt *from)
|
||||
|
||||
COPY_STRING_FIELD(name);
|
||||
COPY_NODE_FIELD(into);
|
||||
COPY_SCALAR_FIELD(into_contains_oids);
|
||||
COPY_SCALAR_FIELD(into_has_oids);
|
||||
COPY_NODE_FIELD(intoOptions);
|
||||
COPY_SCALAR_FIELD(into_on_commit);
|
||||
COPY_STRING_FIELD(into_tbl_space);
|
||||
COPY_NODE_FIELD(params);
|
||||
|
@ -18,7 +18,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.273 2006/06/27 03:43:20 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.274 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -659,6 +659,7 @@ _equalQuery(Query *a, Query *b)
|
||||
COMPARE_SCALAR_FIELD(resultRelation);
|
||||
COMPARE_NODE_FIELD(into);
|
||||
COMPARE_SCALAR_FIELD(intoHasOids);
|
||||
COMPARE_NODE_FIELD(intoOptions);
|
||||
COMPARE_SCALAR_FIELD(intoOnCommit);
|
||||
COMPARE_STRING_FIELD(intoTableSpaceName);
|
||||
COMPARE_SCALAR_FIELD(hasAggs);
|
||||
@ -717,7 +718,7 @@ _equalSelectStmt(SelectStmt *a, SelectStmt *b)
|
||||
COMPARE_NODE_FIELD(distinctClause);
|
||||
COMPARE_NODE_FIELD(into);
|
||||
COMPARE_NODE_FIELD(intoColNames);
|
||||
COMPARE_SCALAR_FIELD(intoHasOids);
|
||||
COMPARE_NODE_FIELD(intoOptions);
|
||||
COMPARE_SCALAR_FIELD(intoOnCommit);
|
||||
COMPARE_STRING_FIELD(intoTableSpaceName);
|
||||
COMPARE_NODE_FIELD(targetList);
|
||||
@ -873,7 +874,7 @@ _equalCreateStmt(CreateStmt *a, CreateStmt *b)
|
||||
COMPARE_NODE_FIELD(tableElts);
|
||||
COMPARE_NODE_FIELD(inhRelations);
|
||||
COMPARE_NODE_FIELD(constraints);
|
||||
COMPARE_SCALAR_FIELD(hasoids);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
COMPARE_SCALAR_FIELD(oncommit);
|
||||
COMPARE_STRING_FIELD(tablespacename);
|
||||
|
||||
@ -951,6 +952,7 @@ _equalIndexStmt(IndexStmt *a, IndexStmt *b)
|
||||
COMPARE_STRING_FIELD(accessMethod);
|
||||
COMPARE_STRING_FIELD(tableSpace);
|
||||
COMPARE_NODE_FIELD(indexParams);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
COMPARE_NODE_FIELD(whereClause);
|
||||
COMPARE_NODE_FIELD(rangetable);
|
||||
COMPARE_SCALAR_FIELD(unique);
|
||||
@ -1471,8 +1473,8 @@ _equalExecuteStmt(ExecuteStmt *a, ExecuteStmt *b)
|
||||
{
|
||||
COMPARE_STRING_FIELD(name);
|
||||
COMPARE_NODE_FIELD(into);
|
||||
COMPARE_SCALAR_FIELD(into_contains_oids);
|
||||
COMPARE_SCALAR_FIELD(into_has_oids);
|
||||
COMPARE_NODE_FIELD(intoOptions);
|
||||
COMPARE_SCALAR_FIELD(into_on_commit);
|
||||
COMPARE_STRING_FIELD(into_tbl_space);
|
||||
COMPARE_NODE_FIELD(params);
|
||||
@ -1673,6 +1675,7 @@ _equalConstraint(Constraint *a, Constraint *b)
|
||||
COMPARE_NODE_FIELD(raw_expr);
|
||||
COMPARE_STRING_FIELD(cooked_expr);
|
||||
COMPARE_NODE_FIELD(keys);
|
||||
COMPARE_NODE_FIELD(options);
|
||||
COMPARE_STRING_FIELD(indexspace);
|
||||
|
||||
return true;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.275 2006/07/01 18:38:32 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.276 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Every node type that can appear in stored rules' parsetrees *must*
|
||||
@ -1325,7 +1325,7 @@ _outCreateStmt(StringInfo str, CreateStmt *node)
|
||||
WRITE_NODE_FIELD(tableElts);
|
||||
WRITE_NODE_FIELD(inhRelations);
|
||||
WRITE_NODE_FIELD(constraints);
|
||||
WRITE_ENUM_FIELD(hasoids, ContainsOids);
|
||||
WRITE_NODE_FIELD(options);
|
||||
WRITE_ENUM_FIELD(oncommit, OnCommitAction);
|
||||
WRITE_STRING_FIELD(tablespacename);
|
||||
}
|
||||
@ -1340,6 +1340,7 @@ _outIndexStmt(StringInfo str, IndexStmt *node)
|
||||
WRITE_STRING_FIELD(accessMethod);
|
||||
WRITE_STRING_FIELD(tableSpace);
|
||||
WRITE_NODE_FIELD(indexParams);
|
||||
WRITE_NODE_FIELD(options);
|
||||
WRITE_NODE_FIELD(whereClause);
|
||||
WRITE_NODE_FIELD(rangetable);
|
||||
WRITE_BOOL_FIELD(unique);
|
||||
@ -1373,7 +1374,7 @@ _outSelectStmt(StringInfo str, SelectStmt *node)
|
||||
WRITE_NODE_FIELD(distinctClause);
|
||||
WRITE_NODE_FIELD(into);
|
||||
WRITE_NODE_FIELD(intoColNames);
|
||||
WRITE_ENUM_FIELD(intoHasOids, ContainsOids);
|
||||
WRITE_NODE_FIELD(intoOptions);
|
||||
WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
|
||||
WRITE_STRING_FIELD(intoTableSpaceName);
|
||||
WRITE_NODE_FIELD(targetList);
|
||||
@ -1509,6 +1510,7 @@ _outQuery(StringInfo str, Query *node)
|
||||
WRITE_INT_FIELD(resultRelation);
|
||||
WRITE_NODE_FIELD(into);
|
||||
WRITE_BOOL_FIELD(intoHasOids);
|
||||
WRITE_NODE_FIELD(intoOptions);
|
||||
WRITE_ENUM_FIELD(intoOnCommit, OnCommitAction);
|
||||
WRITE_STRING_FIELD(intoTableSpaceName);
|
||||
WRITE_BOOL_FIELD(hasAggs);
|
||||
@ -1762,12 +1764,14 @@ _outConstraint(StringInfo str, Constraint *node)
|
||||
case CONSTR_PRIMARY:
|
||||
appendStringInfo(str, "PRIMARY_KEY");
|
||||
WRITE_NODE_FIELD(keys);
|
||||
WRITE_NODE_FIELD(options);
|
||||
WRITE_STRING_FIELD(indexspace);
|
||||
break;
|
||||
|
||||
case CONSTR_UNIQUE:
|
||||
appendStringInfo(str, "UNIQUE");
|
||||
WRITE_NODE_FIELD(keys);
|
||||
WRITE_NODE_FIELD(options);
|
||||
WRITE_STRING_FIELD(indexspace);
|
||||
break;
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.189 2006/04/30 18:30:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.190 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Path and Plan nodes do not have any readfuncs support, because we
|
||||
@ -141,6 +141,7 @@ _readQuery(void)
|
||||
READ_INT_FIELD(resultRelation);
|
||||
READ_NODE_FIELD(into);
|
||||
READ_BOOL_FIELD(intoHasOids);
|
||||
READ_NODE_FIELD(intoOptions);
|
||||
READ_ENUM_FIELD(intoOnCommit, OnCommitAction);
|
||||
READ_STRING_FIELD(intoTableSpaceName);
|
||||
READ_BOOL_FIELD(hasAggs);
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.336 2006/06/27 03:43:20 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.337 2006/07/02 02:23:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -757,7 +757,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt,
|
||||
cxt.blist = NIL;
|
||||
cxt.alist = NIL;
|
||||
cxt.pkey = NULL;
|
||||
cxt.hasoids = interpretOidsOption(stmt->hasoids);
|
||||
cxt.hasoids = interpretOidsOption(stmt->options);
|
||||
|
||||
/*
|
||||
* Run through each primary element in the table creation clause. Separate
|
||||
@ -1282,6 +1282,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
|
||||
|
||||
index->relation = cxt->relation;
|
||||
index->accessMethod = DEFAULT_INDEX_TYPE;
|
||||
index->options = constraint->options;
|
||||
index->tableSpace = constraint->indexspace;
|
||||
index->indexParams = NIL;
|
||||
index->whereClause = NULL;
|
||||
@ -1881,7 +1882,8 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
|
||||
if (stmt->intoColNames)
|
||||
applyColumnNames(qry->targetList, stmt->intoColNames);
|
||||
|
||||
qry->intoHasOids = interpretOidsOption(stmt->intoHasOids);
|
||||
qry->intoHasOids = interpretOidsOption(stmt->intoOptions);
|
||||
qry->intoOptions = copyObject(stmt->intoOptions);
|
||||
qry->intoOnCommit = stmt->intoOnCommit;
|
||||
qry->intoTableSpaceName = stmt->intoTableSpaceName;
|
||||
|
||||
@ -2752,7 +2754,7 @@ transformExecuteStmt(ParseState *pstate, ExecuteStmt *stmt)
|
||||
|
||||
paramtypes = FetchPreparedStatementParams(stmt->name);
|
||||
|
||||
stmt->into_has_oids = interpretOidsOption(stmt->into_contains_oids);
|
||||
stmt->into_has_oids = interpretOidsOption(stmt->intoOptions);
|
||||
|
||||
if (stmt->params || paramtypes)
|
||||
{
|
||||
|
@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.549 2006/07/02 01:58:36 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.550 2006/07/02 02:23:21 momjian Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -53,6 +53,7 @@
|
||||
|
||||
#include "catalog/index.h"
|
||||
#include "catalog/namespace.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "parser/gramparse.h"
|
||||
#include "storage/lmgr.h"
|
||||
@ -123,7 +124,6 @@ static void doNegateFloat(Value *v);
|
||||
JoinType jtype;
|
||||
DropBehavior dbehavior;
|
||||
OnCommitAction oncommit;
|
||||
ContainsOids withoids;
|
||||
List *list;
|
||||
Node *node;
|
||||
Value *value;
|
||||
@ -228,11 +228,11 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
%type <list> stmtblock stmtmulti
|
||||
OptTableElementList TableElementList OptInherit definition
|
||||
opt_distinct opt_definition func_args func_args_list
|
||||
OptWith opt_distinct opt_definition func_args func_args_list
|
||||
func_as createfunc_opt_list alterfunc_opt_list
|
||||
aggr_args aggr_args_list old_aggr_definition old_aggr_list
|
||||
oper_argtypes RuleActionList RuleActionMulti
|
||||
opt_column_list columnList opt_name_list
|
||||
opt_column_list columnList opt_name_list
|
||||
sort_clause opt_sort_clause sortby_list index_params
|
||||
name_list from_clause from_list opt_array_bounds
|
||||
qualified_name_list any_name any_name_list
|
||||
@ -255,7 +255,6 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
%type <boolean> TriggerForType OptTemp
|
||||
%type <oncommit> OnCommitOption
|
||||
%type <withoids> OptWithOids
|
||||
|
||||
%type <node> for_locking_item
|
||||
%type <list> for_locking_clause opt_for_locking_clause for_locking_items
|
||||
@ -1559,6 +1558,32 @@ alter_rel_cmd:
|
||||
n->name = $3;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
/* ALTER [TABLE|INDEX] <name> SET (...) */
|
||||
| SET definition
|
||||
{
|
||||
AlterTableCmd *n = makeNode(AlterTableCmd);
|
||||
n->subtype = AT_SetOptions;
|
||||
n->def = (Node *)$2;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| RESET definition
|
||||
{
|
||||
AlterTableCmd *n;
|
||||
ListCell *cell;
|
||||
|
||||
foreach(cell, $2)
|
||||
{
|
||||
if (((DefElem *) lfirst(cell))->arg != NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SYNTAX_ERROR),
|
||||
errmsg("parameters for RESET should not take values")));
|
||||
}
|
||||
|
||||
n = makeNode(AlterTableCmd);
|
||||
n->subtype = AT_SetOptions;
|
||||
n->def = (Node *)$2;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
|
||||
alter_column_default:
|
||||
@ -1744,7 +1769,7 @@ opt_using:
|
||||
*****************************************************************************/
|
||||
|
||||
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
|
||||
OptInherit OptWithOids OnCommitOption OptTableSpace
|
||||
OptInherit OptWith OnCommitOption OptTableSpace
|
||||
{
|
||||
CreateStmt *n = makeNode(CreateStmt);
|
||||
$4->istemp = $2;
|
||||
@ -1752,13 +1777,13 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
|
||||
n->tableElts = $6;
|
||||
n->inhRelations = $8;
|
||||
n->constraints = NIL;
|
||||
n->hasoids = $9;
|
||||
n->options = $9;
|
||||
n->oncommit = $10;
|
||||
n->tablespacename = $11;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CREATE OptTemp TABLE qualified_name OF qualified_name
|
||||
'(' OptTableElementList ')' OptWithOids OnCommitOption OptTableSpace
|
||||
'(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace
|
||||
{
|
||||
/* SQL99 CREATE TABLE OF <UDT> (cols) seems to be satisfied
|
||||
* by our inheritance capabilities. Let's try it...
|
||||
@ -1769,7 +1794,7 @@ CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
|
||||
n->tableElts = $8;
|
||||
n->inhRelations = list_make1($6);
|
||||
n->constraints = NIL;
|
||||
n->hasoids = $10;
|
||||
n->options = $10;
|
||||
n->oncommit = $11;
|
||||
n->tablespacename = $12;
|
||||
$$ = (Node *)n;
|
||||
@ -1905,7 +1930,7 @@ ColConstraintElem:
|
||||
n->indexspace = $2;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| PRIMARY KEY OptConsTableSpace
|
||||
| PRIMARY KEY opt_definition OptConsTableSpace
|
||||
{
|
||||
Constraint *n = makeNode(Constraint);
|
||||
n->contype = CONSTR_PRIMARY;
|
||||
@ -1913,7 +1938,8 @@ ColConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = NULL;
|
||||
n->indexspace = $3;
|
||||
n->options = $3;
|
||||
n->indexspace = $4;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CHECK '(' a_expr ')'
|
||||
@ -2085,7 +2111,7 @@ ConstraintElem:
|
||||
n->indexspace = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| PRIMARY KEY '(' columnList ')' OptConsTableSpace
|
||||
| PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace
|
||||
{
|
||||
Constraint *n = makeNode(Constraint);
|
||||
n->contype = CONSTR_PRIMARY;
|
||||
@ -2093,7 +2119,8 @@ ConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = $4;
|
||||
n->indexspace = $6;
|
||||
n->options = $6;
|
||||
n->indexspace = $7;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name
|
||||
@ -2187,10 +2214,13 @@ OptInherit: INHERITS '(' qualified_name_list ')' { $$ = $3; }
|
||||
| /*EMPTY*/ { $$ = NIL; }
|
||||
;
|
||||
|
||||
OptWithOids:
|
||||
WITH OIDS { $$ = MUST_HAVE_OIDS; }
|
||||
| WITHOUT OIDS { $$ = MUST_NOT_HAVE_OIDS; }
|
||||
| /*EMPTY*/ { $$ = DEFAULT_OIDS; }
|
||||
OptWith:
|
||||
WITH OIDS { $$ = list_make1(defWithOids(true)); }
|
||||
| WITHOUT OIDS { $$ = list_make1(defWithOids(false)); }
|
||||
| WITH definition { $$ = $2; }
|
||||
| WITH OIDS WITH definition { $$ = lappend($4, defWithOids(true)); }
|
||||
| WITHOUT OIDS WITH definition { $$ = lappend($4, defWithOids(false)); }
|
||||
| /*EMPTY*/ { $$ = NIL; }
|
||||
;
|
||||
|
||||
OnCommitOption: ON COMMIT DROP { $$ = ONCOMMIT_DROP; }
|
||||
@ -2215,7 +2245,7 @@ OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; }
|
||||
|
||||
CreateAsStmt:
|
||||
CREATE OptTemp TABLE qualified_name OptCreateAs
|
||||
OptWithOids OnCommitOption OptTableSpace AS SelectStmt
|
||||
OptWith OnCommitOption OptTableSpace AS SelectStmt
|
||||
{
|
||||
/*
|
||||
* When the SelectStmt is a set-operation tree, we must
|
||||
@ -2232,7 +2262,7 @@ CreateAsStmt:
|
||||
$4->istemp = $2;
|
||||
n->into = $4;
|
||||
n->intoColNames = $5;
|
||||
n->intoHasOids = $6;
|
||||
n->intoOptions = $6;
|
||||
n->intoOnCommit = $7;
|
||||
n->intoTableSpaceName = $8;
|
||||
$$ = $10;
|
||||
@ -3630,7 +3660,7 @@ opt_granted_by: GRANTED BY RoleId { $$ = $3; }
|
||||
*****************************************************************************/
|
||||
|
||||
IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name
|
||||
access_method_clause '(' index_params ')' OptTableSpace where_clause
|
||||
access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
|
||||
{
|
||||
IndexStmt *n = makeNode(IndexStmt);
|
||||
n->unique = $2;
|
||||
@ -3638,8 +3668,9 @@ IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name
|
||||
n->relation = $6;
|
||||
n->accessMethod = $7;
|
||||
n->indexParams = $9;
|
||||
n->tableSpace = $11;
|
||||
n->whereClause = $12;
|
||||
n->options = $11;
|
||||
n->tableSpace = $12;
|
||||
n->whereClause = $13;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
;
|
||||
@ -5264,7 +5295,7 @@ ExecuteStmt: EXECUTE name execute_param_clause
|
||||
$$ = (Node *) n;
|
||||
}
|
||||
| CREATE OptTemp TABLE qualified_name OptCreateAs
|
||||
OptWithOids OnCommitOption OptTableSpace AS
|
||||
OptWith OnCommitOption OptTableSpace AS
|
||||
EXECUTE name execute_param_clause
|
||||
{
|
||||
ExecuteStmt *n = makeNode(ExecuteStmt);
|
||||
@ -5272,7 +5303,7 @@ ExecuteStmt: EXECUTE name execute_param_clause
|
||||
n->params = $12;
|
||||
$4->istemp = $2;
|
||||
n->into = $4;
|
||||
n->into_contains_oids = $6;
|
||||
n->intoOptions = $6;
|
||||
n->into_on_commit = $7;
|
||||
n->into_tbl_space = $8;
|
||||
if ($5)
|
||||
@ -5606,7 +5637,6 @@ simple_select:
|
||||
n->targetList = $3;
|
||||
n->into = $4;
|
||||
n->intoColNames = NIL;
|
||||
n->intoHasOids = DEFAULT_OIDS;
|
||||
n->fromClause = $5;
|
||||
n->whereClause = $6;
|
||||
n->groupClause = $7;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.149 2006/03/16 00:31:55 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/parse_clause.c,v 1.150 2006/07/02 02:23:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#include "optimizer/clauses.h"
|
||||
#include "optimizer/tlist.h"
|
||||
@ -33,6 +34,7 @@
|
||||
#include "rewrite/rewriteManip.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/guc.h"
|
||||
#include "utils/memutils.h"
|
||||
|
||||
|
||||
#define ORDER_CLAUSE 0
|
||||
@ -64,6 +66,8 @@ static Node *buildMergedJoinVar(ParseState *pstate, JoinType jointype,
|
||||
Var *l_colvar, Var *r_colvar);
|
||||
static TargetEntry *findTargetlistEntry(ParseState *pstate, Node *node,
|
||||
List **tlist, int clause);
|
||||
static bool OptionMatches(text *t, const char* kw, char **str, Size *len);
|
||||
static Datum OptionToText(DefElem *def);
|
||||
|
||||
|
||||
/*
|
||||
@ -212,29 +216,280 @@ interpretInhOption(InhOption inhOpt)
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an enum that indicates whether WITH / WITHOUT OIDS was
|
||||
* Given a List that indicates whether WITH / WITHOUT OIDS was
|
||||
* specified by the user, return true iff the specified 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 default_with_oids GUC var.
|
||||
*/
|
||||
bool
|
||||
interpretOidsOption(ContainsOids opt)
|
||||
interpretOidsOption(List *options)
|
||||
{
|
||||
switch (opt)
|
||||
ListCell *cell;
|
||||
|
||||
foreach(cell, options)
|
||||
{
|
||||
case MUST_HAVE_OIDS:
|
||||
return true;
|
||||
DefElem *def = (DefElem *) lfirst(cell);
|
||||
|
||||
case MUST_NOT_HAVE_OIDS:
|
||||
return false;
|
||||
|
||||
case DEFAULT_OIDS:
|
||||
return default_with_oids;
|
||||
if (pg_strcasecmp(def->defname, "oids") == 0)
|
||||
return defGetBoolean(def);
|
||||
}
|
||||
|
||||
elog(ERROR, "bogus ContainsOids value: %d", opt);
|
||||
return false; /* keep compiler quiet */
|
||||
/* oids option is not specified. */
|
||||
return default_with_oids;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test if t is start with 'kw='.
|
||||
*/
|
||||
static bool
|
||||
OptionMatches(text *t, const char* kw, char **str, Size *len)
|
||||
{
|
||||
char *text_str = (char *) VARATT_DATA(t);
|
||||
int text_len = VARATT_SIZE(t) - VARHDRSZ;
|
||||
Size kwlen = strlen(kw);
|
||||
|
||||
if (text_len > kwlen && text_str[kwlen] == '=' &&
|
||||
pg_strncasecmp(text_str, kw, kwlen) == 0)
|
||||
{
|
||||
*str = text_str + kwlen + 1;
|
||||
*len = text_len - kwlen - 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flatten a DefElem to a text like as 'defname=arg'.
|
||||
*/
|
||||
static Datum
|
||||
OptionToText(DefElem *def)
|
||||
{
|
||||
text *t;
|
||||
char *value = defGetString(def);
|
||||
Size len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
|
||||
|
||||
t = palloc(len + 1);
|
||||
VARATT_SIZEP(t) = len;
|
||||
sprintf((char *) VARATT_DATA(t), "%s=%s", def->defname, value);
|
||||
|
||||
return PointerGetDatum(t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Merge option array and option list.
|
||||
*
|
||||
* array Existing option, or NULL if new option.
|
||||
* list List of DefElems to be added to array.
|
||||
*/
|
||||
ArrayType *
|
||||
OptionBuild(ArrayType *array, List *list)
|
||||
{
|
||||
ListCell *cell;
|
||||
bool *used;
|
||||
int index;
|
||||
int o;
|
||||
ArrayType *result;
|
||||
ArrayBuildState *astate;
|
||||
MemoryContext myContext;
|
||||
MemoryContext oldContext;
|
||||
|
||||
if (list_length(list) == 0)
|
||||
{
|
||||
/* no additinal elements, so just clone. */
|
||||
if (array == NULL)
|
||||
return NULL;
|
||||
result = palloc(VARATT_SIZE(array));
|
||||
memcpy(result, array, VARATT_SIZE(array));
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Make a temporary context to hold all the junk */
|
||||
myContext = AllocSetContextCreate(CurrentMemoryContext,
|
||||
"OptionBuild",
|
||||
ALLOCSET_DEFAULT_MINSIZE,
|
||||
ALLOCSET_DEFAULT_INITSIZE,
|
||||
ALLOCSET_DEFAULT_MAXSIZE);
|
||||
oldContext = MemoryContextSwitchTo(myContext);
|
||||
|
||||
astate = NULL;
|
||||
used = (bool *) palloc0(sizeof(bool) * list_length(list));
|
||||
|
||||
if (array)
|
||||
{
|
||||
Assert(ARR_ELEMTYPE(array) == TEXTOID);
|
||||
Assert(ARR_NDIM(array) == 1);
|
||||
Assert(ARR_LBOUND(array)[0] == 1);
|
||||
|
||||
for (o = 1; o <= ARR_DIMS(array)[0]; o++)
|
||||
{
|
||||
bool isnull;
|
||||
Datum datum;
|
||||
|
||||
datum = array_ref(array, 1, &o,
|
||||
-1 /* varlenarray */ ,
|
||||
-1 /* TEXT's typlen */ ,
|
||||
false /* TEXT's typbyval */ ,
|
||||
'i' /* TEXT's typalign */ ,
|
||||
&isnull);
|
||||
if (isnull)
|
||||
continue;
|
||||
|
||||
index = 0;
|
||||
foreach(cell, list)
|
||||
{
|
||||
DefElem *def = lfirst(cell);
|
||||
|
||||
/*
|
||||
* We ignore 'oids' item because it is stored
|
||||
* in pg_class.relhasoids.
|
||||
*/
|
||||
if (!used[index] &&
|
||||
pg_strcasecmp(def->defname, "oids") != 0)
|
||||
{
|
||||
char *value_str;
|
||||
Size value_len;
|
||||
if (OptionMatches(DatumGetTextP(datum),
|
||||
def->defname, &value_str, &value_len))
|
||||
{
|
||||
used[index] = true;
|
||||
if (def->arg)
|
||||
{
|
||||
/* Replace an existing option. */
|
||||
datum = OptionToText(def);
|
||||
goto next; /* skip remain items in list */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove the option from array. */
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
/*
|
||||
* The datum is an existing parameter and is not modified.
|
||||
* Fall down.
|
||||
*/
|
||||
|
||||
next:
|
||||
astate = accumArrayResult(astate, datum, false, TEXTOID, myContext);
|
||||
skip:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add options not in array
|
||||
*/
|
||||
index = 0;
|
||||
foreach(cell, list)
|
||||
{
|
||||
DefElem *def = lfirst(cell);
|
||||
|
||||
if (!used[index] && def->arg &&
|
||||
pg_strcasecmp(def->defname, "oids") != 0)
|
||||
{
|
||||
astate = accumArrayResult(astate, OptionToText(def),
|
||||
false, TEXTOID, myContext);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
if (astate)
|
||||
result = DatumGetArrayTypeP(makeArrayResult(astate, oldContext));
|
||||
else
|
||||
result = NULL;
|
||||
|
||||
MemoryContextSwitchTo(oldContext);
|
||||
MemoryContextDelete(myContext);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Support routine to parse options.
|
||||
*
|
||||
* options List of DefElems
|
||||
* num length of kwds
|
||||
* kwds supported keywords
|
||||
* strict Throw error if unsupported option is found.
|
||||
*
|
||||
* FIXME: memory is leaked in kwds[].arg.
|
||||
*/
|
||||
void
|
||||
OptionParse(ArrayType *options, Size num, DefElem kwds[], bool strict)
|
||||
{
|
||||
Size k;
|
||||
int o;
|
||||
|
||||
for (k = 0; k < num; k++)
|
||||
{
|
||||
Assert(kwds[k].defname);
|
||||
kwds[k].arg = NULL;
|
||||
}
|
||||
|
||||
if (options == NULL)
|
||||
return; /* use default for all */
|
||||
|
||||
Assert(ARR_ELEMTYPE(options) == TEXTOID);
|
||||
Assert(ARR_NDIM(options) == 1);
|
||||
Assert(ARR_LBOUND(options)[0] == 1);
|
||||
|
||||
for (o = 1; o <= ARR_DIMS(options)[0]; o++)
|
||||
{
|
||||
bool isnull;
|
||||
Datum datum;
|
||||
|
||||
datum = array_ref(options, 1, &o,
|
||||
-1 /* varlenarray */ ,
|
||||
-1 /* TEXT's typlen */ ,
|
||||
false /* TEXT's typbyval */ ,
|
||||
'i' /* TEXT's typalign */ ,
|
||||
&isnull);
|
||||
if (isnull)
|
||||
continue;
|
||||
|
||||
for (k = 0; k < num; k++)
|
||||
{
|
||||
char *value_str;
|
||||
Size value_len;
|
||||
|
||||
if (OptionMatches(DatumGetTextP(datum),
|
||||
kwds[k].defname, &value_str, &value_len))
|
||||
{
|
||||
char *value;
|
||||
|
||||
if (kwds[k].arg != NULL)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("duplicated parameter %s",
|
||||
kwds[k].defname)));
|
||||
|
||||
/* copy value as Value node */
|
||||
value = (char *) palloc(value_len + 1);
|
||||
strncpy(value, value_str, value_len);
|
||||
value[value_len] = '\0';
|
||||
kwds[k].arg = (Node *) makeString(value);
|
||||
goto next; /* skip remain keywords */
|
||||
}
|
||||
}
|
||||
|
||||
/* parameter is not in kwds */
|
||||
if (strict)
|
||||
{
|
||||
char *c = DatumGetCString(DirectFunctionCall1(textout, datum));
|
||||
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("unsupported parameter %s", c)));
|
||||
}
|
||||
next:;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -10,7 +10,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.258 2006/06/16 20:23:44 adunstan Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/utility.c,v 1.259 2006/07/02 02:23:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -794,6 +794,7 @@ ProcessUtility(Node *parsetree,
|
||||
stmt->indexParams, /* parameters */
|
||||
(Expr *) stmt->whereClause,
|
||||
stmt->rangetable,
|
||||
stmt->options,
|
||||
stmt->unique,
|
||||
stmt->primary,
|
||||
stmt->isconstraint,
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ruleutils.c - Functions to convert stored expressions/querytrees
|
||||
* back to source text
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.224 2006/06/16 18:42:22 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.225 2006/07/02 02:23:21 momjian Exp $
|
||||
**********************************************************************/
|
||||
|
||||
#include "postgres.h"
|
||||
@ -187,6 +187,7 @@ static char *generate_relation_name(Oid relid);
|
||||
static char *generate_function_name(Oid funcid, int nargs, Oid *argtypes);
|
||||
static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2);
|
||||
static text *string_to_text(char *str);
|
||||
static char *flatten_reloptions(Oid relid);
|
||||
|
||||
#define only_marker(rte) ((rte)->inh ? "" : "ONLY ")
|
||||
|
||||
@ -756,9 +757,20 @@ pg_get_indexdef_worker(Oid indexrelid, int colno, int prettyFlags)
|
||||
}
|
||||
|
||||
if (!colno)
|
||||
{
|
||||
appendStringInfoChar(&buf, ')');
|
||||
|
||||
/*
|
||||
* If it has options, append "WITH (options)"
|
||||
*/
|
||||
str = flatten_reloptions(indexrelid);
|
||||
if (str)
|
||||
{
|
||||
appendStringInfo(&buf, " WITH (%s)", str);
|
||||
pfree(str);
|
||||
}
|
||||
|
||||
if (!colno)
|
||||
{
|
||||
/*
|
||||
* If it's a partial index, decompile and append the predicate
|
||||
*/
|
||||
@ -1004,6 +1016,17 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
|
||||
decompile_column_index_array(val, conForm->conrelid, &buf);
|
||||
|
||||
appendStringInfo(&buf, ")");
|
||||
|
||||
if (fullCommand && OidIsValid(conForm->conrelid))
|
||||
{
|
||||
char *options = flatten_reloptions(conForm->conrelid);
|
||||
if (options)
|
||||
{
|
||||
appendStringInfo(&buf, " WITH (%s)", options);
|
||||
pfree(options);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case CONSTRAINT_CHECK:
|
||||
@ -4913,3 +4936,36 @@ string_to_text(char *str)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static char *
|
||||
flatten_reloptions(Oid relid)
|
||||
{
|
||||
HeapTuple tuple;
|
||||
char *result = NULL;
|
||||
|
||||
tuple = SearchSysCache(RELOID,
|
||||
ObjectIdGetDatum(relid),
|
||||
0, 0, 0);
|
||||
if (tuple)
|
||||
{
|
||||
bool isnull;
|
||||
Datum reloptions;
|
||||
reloptions = SysCacheGetAttr(RELOID, tuple,
|
||||
Anum_pg_class_reloptions, &isnull);
|
||||
if (!isnull)
|
||||
{
|
||||
Datum sep,
|
||||
txt;
|
||||
sep = DirectFunctionCall1(textin, CStringGetDatum(", "));
|
||||
/*
|
||||
* OID 395 = array_to_text.
|
||||
* DirectFunctionCall2(array_to_text) is not available here.
|
||||
*/
|
||||
txt = OidFunctionCall2(395, reloptions, sep);
|
||||
result = DatumGetCString(DirectFunctionCall1(textout, txt));
|
||||
}
|
||||
ReleaseSysCache(tuple);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
171
src/backend/utils/cache/relcache.c
vendored
171
src/backend/utils/cache/relcache.c
vendored
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.242 2006/06/16 18:42:22 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.243 2006/07/02 02:23:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -47,6 +47,8 @@
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/pg_rewrite.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "catalog/index.h"
|
||||
#include "commands/trigger.h"
|
||||
#include "miscadmin.h"
|
||||
#include "optimizer/clauses.h"
|
||||
@ -54,6 +56,7 @@
|
||||
#include "optimizer/prep.h"
|
||||
#include "storage/fd.h"
|
||||
#include "storage/smgr.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/catcache.h"
|
||||
#include "utils/fmgroids.h"
|
||||
@ -71,7 +74,7 @@
|
||||
*/
|
||||
#define RELCACHE_INIT_FILENAME "pg_internal.init"
|
||||
|
||||
#define RELCACHE_INIT_FILEMAGIC 0x573262 /* version ID value */
|
||||
#define RELCACHE_INIT_FILEMAGIC 0x573263 /* version ID value */
|
||||
|
||||
/*
|
||||
* hardcoded tuple descriptors. see include/catalog/pg_attribute.h
|
||||
@ -183,6 +186,7 @@ static void RelationClearRelation(Relation relation, bool rebuild);
|
||||
static void RelationReloadClassinfo(Relation relation);
|
||||
static void RelationFlushRelation(Relation relation);
|
||||
static bool load_relcache_init_file(void);
|
||||
static void write_item(const void *data, Size len, FILE *fp);
|
||||
static void write_relcache_init_file(void);
|
||||
|
||||
static void formrdesc(const char *relationName, Oid relationReltype,
|
||||
@ -206,6 +210,7 @@ static void IndexSupportInitialize(oidvector *indclass,
|
||||
static OpClassCacheEnt *LookupOpclassInfo(Oid operatorClassOid,
|
||||
StrategyNumber numStrats,
|
||||
StrategyNumber numSupport);
|
||||
static void RelationParseOptions(Relation relation, HeapTuple tuple);
|
||||
|
||||
|
||||
/*
|
||||
@ -309,6 +314,7 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
||||
|
||||
/* initialize relation tuple form */
|
||||
relation->rd_rel = relationForm;
|
||||
relation->rd_options = NULL;
|
||||
|
||||
/* and allocate attribute tuple form storage */
|
||||
relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts,
|
||||
@ -321,6 +327,53 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
|
||||
return relation;
|
||||
}
|
||||
|
||||
/*
|
||||
* RelationParseOptions
|
||||
*/
|
||||
static void
|
||||
RelationParseOptions(Relation relation, HeapTuple tuple)
|
||||
{
|
||||
ArrayType *options;
|
||||
|
||||
Assert(tuple);
|
||||
|
||||
switch (relation->rd_rel->relkind)
|
||||
{
|
||||
case RELKIND_RELATION:
|
||||
case RELKIND_TOASTVALUE:
|
||||
case RELKIND_UNCATALOGED:
|
||||
case RELKIND_INDEX:
|
||||
break;
|
||||
default:
|
||||
/* other relation should not have options. */
|
||||
relation->rd_options = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* SysCacheGetAttr is not available here. */
|
||||
if (heap_attisnull(tuple, Anum_pg_class_reloptions))
|
||||
options = NULL;
|
||||
else
|
||||
options = (ArrayType *) ((Form_pg_class) GETSTRUCT(tuple))->reloptions;
|
||||
|
||||
switch (relation->rd_rel->relkind)
|
||||
{
|
||||
case RELKIND_RELATION:
|
||||
case RELKIND_TOASTVALUE:
|
||||
case RELKIND_UNCATALOGED:
|
||||
relation->rd_options = heap_option(
|
||||
relation->rd_rel->relkind, options);
|
||||
break;
|
||||
case RELKIND_INDEX:
|
||||
relation->rd_options = index_option(
|
||||
relation->rd_am->amoption, options);
|
||||
break;
|
||||
default:
|
||||
/* should not happen */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* RelationBuildTupleDesc
|
||||
*
|
||||
@ -725,11 +778,6 @@ RelationBuildDesc(Oid targetRelId, Relation oldrelation)
|
||||
*/
|
||||
relation = AllocateRelationDesc(oldrelation, relp);
|
||||
|
||||
/*
|
||||
* now we can free the memory allocated for pg_class_tuple
|
||||
*/
|
||||
heap_freetuple(pg_class_tuple);
|
||||
|
||||
/*
|
||||
* initialize the relation's relation id (relation->rd_id)
|
||||
*/
|
||||
@ -785,6 +833,14 @@ RelationBuildDesc(Oid targetRelId, Relation oldrelation)
|
||||
/* make sure relation is marked as having no open file yet */
|
||||
relation->rd_smgr = NULL;
|
||||
|
||||
/* Build AM-specific fields. */
|
||||
RelationParseOptions(relation, pg_class_tuple);
|
||||
|
||||
/*
|
||||
* now we can free the memory allocated for pg_class_tuple
|
||||
*/
|
||||
heap_freetuple(pg_class_tuple);
|
||||
|
||||
/*
|
||||
* Insert newly created relation into relcache hash tables.
|
||||
*/
|
||||
@ -1210,6 +1266,7 @@ formrdesc(const char *relationName, Oid relationReltype,
|
||||
* data from pg_class and replace what we've done here.
|
||||
*/
|
||||
relation->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
|
||||
relation->rd_options = NULL;
|
||||
|
||||
namestrcpy(&relation->rd_rel->relname, relationName);
|
||||
relation->rd_rel->relnamespace = PG_CATALOG_NAMESPACE;
|
||||
@ -1297,6 +1354,11 @@ formrdesc(const char *relationName, Oid relationReltype,
|
||||
relation->rd_rel->relhasindex = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize the rd_options field to default value
|
||||
*/
|
||||
relation->rd_options = heap_option(RELKIND_RELATION, NULL);
|
||||
|
||||
/*
|
||||
* add new reldesc to relcache
|
||||
*/
|
||||
@ -1475,6 +1537,9 @@ RelationReloadClassinfo(Relation relation)
|
||||
RelationGetRelid(relation));
|
||||
relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
|
||||
memcpy(relation->rd_rel, relp, CLASS_TUPLE_SIZE);
|
||||
if (relation->rd_options)
|
||||
pfree(relation->rd_options);
|
||||
RelationParseOptions(relation, pg_class_tuple);
|
||||
heap_freetuple(pg_class_tuple);
|
||||
/* We must recalculate physical address in case it changed */
|
||||
RelationInitPhysicalAddr(relation);
|
||||
@ -1581,6 +1646,8 @@ RelationClearRelation(Relation relation, bool rebuild)
|
||||
pfree(relation->rd_am);
|
||||
if (relation->rd_rel)
|
||||
pfree(relation->rd_rel);
|
||||
if (relation->rd_options)
|
||||
pfree(relation->rd_options);
|
||||
list_free(relation->rd_indexlist);
|
||||
if (relation->rd_indexcxt)
|
||||
MemoryContextDelete(relation->rd_indexcxt);
|
||||
@ -2111,6 +2178,7 @@ RelationBuildLocalRelation(const char *relname,
|
||||
* initialize relation tuple form (caller may add/override data later)
|
||||
*/
|
||||
rel->rd_rel = (Form_pg_class) palloc0(CLASS_TUPLE_SIZE);
|
||||
rel->rd_options = NULL;
|
||||
|
||||
namestrcpy(&rel->rd_rel->relname, relname);
|
||||
rel->rd_rel->relnamespace = relnamespace;
|
||||
@ -3032,6 +3100,22 @@ load_relcache_init_file(void)
|
||||
has_not_null |= rel->rd_att->attrs[i]->attnotnull;
|
||||
}
|
||||
|
||||
/* next read the access method specific field */
|
||||
if ((nread = fread(&len, 1, sizeof(len), fp)) != sizeof(len))
|
||||
goto read_failed;
|
||||
if (len > 0)
|
||||
{
|
||||
rel->rd_options = palloc(len);
|
||||
if ((nread = fread(rel->rd_options, 1, len, fp)) != len)
|
||||
goto read_failed;
|
||||
if (len != VARATT_SIZE(rel->rd_options))
|
||||
goto read_failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
rel->rd_options = NULL;
|
||||
}
|
||||
|
||||
/* mark not-null status */
|
||||
if (has_not_null)
|
||||
{
|
||||
@ -3215,6 +3299,15 @@ read_failed:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
write_item(const void *data, Size len, FILE *fp)
|
||||
{
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
if (fwrite(data, 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out a new initialization file with the current contents
|
||||
* of the relcache.
|
||||
@ -3277,39 +3370,24 @@ write_relcache_init_file(void)
|
||||
{
|
||||
Relation rel = idhentry->reldesc;
|
||||
Form_pg_class relform = rel->rd_rel;
|
||||
Size len;
|
||||
|
||||
/*
|
||||
* first write the relcache entry proper
|
||||
*/
|
||||
len = sizeof(RelationData);
|
||||
|
||||
/* first, write the relation descriptor length */
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
|
||||
/* next, write out the Relation structure */
|
||||
if (fwrite(rel, 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
/* first write the relcache entry proper */
|
||||
write_item(rel, sizeof(RelationData), fp);
|
||||
|
||||
/* next write the relation tuple form */
|
||||
len = sizeof(FormData_pg_class);
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
|
||||
if (fwrite(relform, 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
write_item(relform, CLASS_TUPLE_SIZE, fp);
|
||||
|
||||
/* next, do all the attribute tuple form data entries */
|
||||
for (i = 0; i < relform->relnatts; i++)
|
||||
{
|
||||
len = ATTRIBUTE_TUPLE_SIZE;
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
if (fwrite(rel->rd_att->attrs[i], 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
write_item(rel->rd_att->attrs[i],
|
||||
ATTRIBUTE_TUPLE_SIZE, fp);
|
||||
}
|
||||
|
||||
/* next, do the access method specific field */
|
||||
write_item(rel->rd_options,
|
||||
(rel->rd_options ? VARATT_SIZE(rel->rd_options) : 0), fp);
|
||||
|
||||
/* If it's an index, there's more to do */
|
||||
if (rel->rd_rel->relkind == RELKIND_INDEX)
|
||||
{
|
||||
@ -3317,36 +3395,19 @@ write_relcache_init_file(void)
|
||||
|
||||
/* write the pg_index tuple */
|
||||
/* we assume this was created by heap_copytuple! */
|
||||
len = HEAPTUPLESIZE + rel->rd_indextuple->t_len;
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
|
||||
if (fwrite(rel->rd_indextuple, 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
write_item(rel->rd_indextuple,
|
||||
HEAPTUPLESIZE + rel->rd_indextuple->t_len, fp);
|
||||
|
||||
/* next, write the access method tuple form */
|
||||
len = sizeof(FormData_pg_am);
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
|
||||
if (fwrite(am, 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
write_item(am, sizeof(FormData_pg_am), fp);
|
||||
|
||||
/* next, write the vector of operator OIDs */
|
||||
len = relform->relnatts * (am->amstrategies * sizeof(Oid));
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
|
||||
if (fwrite(rel->rd_operator, 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
write_item(rel->rd_operator, relform->relnatts *
|
||||
(am->amstrategies * sizeof(Oid)), fp);
|
||||
|
||||
/* finally, write the vector of support procedures */
|
||||
len = relform->relnatts * (am->amsupport * sizeof(RegProcedure));
|
||||
if (fwrite(&len, 1, sizeof(len), fp) != sizeof(len))
|
||||
elog(FATAL, "could not write init file");
|
||||
|
||||
if (fwrite(rel->rd_support, 1, len, fp) != len)
|
||||
elog(FATAL, "could not write init file");
|
||||
write_item(rel->rd_support, relform->relnatts *
|
||||
(am->amsupport * sizeof(RegProcedure)), fp);
|
||||
}
|
||||
|
||||
/* also make a list of their OIDs, for RelationIdIsInInitFile */
|
||||
|
@ -12,7 +12,7 @@
|
||||
* by PostgreSQL
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.438 2006/06/09 19:46:09 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.439 2006/07/02 02:23:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -2594,6 +2594,7 @@ getTables(int *numTables)
|
||||
int i_owning_tab;
|
||||
int i_owning_col;
|
||||
int i_reltablespace;
|
||||
int i_reloptions;
|
||||
|
||||
/* Make sure we are in proper schema */
|
||||
selectSourceSchema("pg_catalog");
|
||||
@ -2618,7 +2619,7 @@ getTables(int *numTables)
|
||||
* we cannot correctly identify inherited columns, serial columns, etc.
|
||||
*/
|
||||
|
||||
if (g_fout->remoteVersion >= 80000)
|
||||
if (g_fout->remoteVersion >= 80200)
|
||||
{
|
||||
/*
|
||||
* Left join to pick up dependency info linking sequences to their
|
||||
@ -2632,7 +2633,37 @@ getTables(int *numTables)
|
||||
"relhasindex, relhasrules, relhasoids, "
|
||||
"d.refobjid as owning_tab, "
|
||||
"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 "
|
||||
"from pg_class c "
|
||||
"left join pg_depend d on "
|
||||
"(c.relkind = '%c' and "
|
||||
"d.classid = c.tableoid and d.objid = c.oid and "
|
||||
"d.objsubid = 0 and "
|
||||
"d.refclassid = c.tableoid and d.deptype = 'i') "
|
||||
"where relkind in ('%c', '%c', '%c', '%c') "
|
||||
"order by c.oid",
|
||||
username_subquery,
|
||||
RELKIND_SEQUENCE,
|
||||
RELKIND_RELATION, RELKIND_SEQUENCE,
|
||||
RELKIND_VIEW, RELKIND_COMPOSITE_TYPE);
|
||||
}
|
||||
else if (g_fout->remoteVersion >= 80000)
|
||||
{
|
||||
/*
|
||||
* Left join to pick up dependency info linking sequences to their
|
||||
* serial column, if any
|
||||
*/
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT c.tableoid, c.oid, relname, "
|
||||
"relacl, relkind, relnamespace, "
|
||||
"(%s relowner) as rolname, "
|
||||
"relchecks, reltriggers, "
|
||||
"relhasindex, relhasrules, relhasoids, "
|
||||
"d.refobjid as owning_tab, "
|
||||
"d.refobjsubid as owning_col, "
|
||||
"(SELECT spcname FROM pg_tablespace t WHERE t.oid = c.reltablespace) AS reltablespace, "
|
||||
"NULL as reloptions "
|
||||
"from pg_class c "
|
||||
"left join pg_depend d on "
|
||||
"(c.relkind = '%c' and "
|
||||
@ -2660,7 +2691,8 @@ getTables(int *numTables)
|
||||
"relhasindex, relhasrules, relhasoids, "
|
||||
"d.refobjid as owning_tab, "
|
||||
"d.refobjsubid as owning_col, "
|
||||
"NULL as reltablespace "
|
||||
"NULL as reltablespace, "
|
||||
"NULL as reloptions "
|
||||
"from pg_class c "
|
||||
"left join pg_depend d on "
|
||||
"(c.relkind = '%c' and "
|
||||
@ -2684,7 +2716,8 @@ getTables(int *numTables)
|
||||
"relhasindex, relhasrules, relhasoids, "
|
||||
"NULL::oid as owning_tab, "
|
||||
"NULL::int4 as owning_col, "
|
||||
"NULL as reltablespace "
|
||||
"NULL as reltablespace, "
|
||||
"NULL as reloptions "
|
||||
"from pg_class "
|
||||
"where relkind in ('%c', '%c', '%c') "
|
||||
"order by oid",
|
||||
@ -2703,7 +2736,8 @@ getTables(int *numTables)
|
||||
"'t'::bool as relhasoids, "
|
||||
"NULL::oid as owning_tab, "
|
||||
"NULL::int4 as owning_col, "
|
||||
"NULL as reltablespace "
|
||||
"NULL as reltablespace, "
|
||||
"NULL as reloptions "
|
||||
"from pg_class "
|
||||
"where relkind in ('%c', '%c', '%c') "
|
||||
"order by oid",
|
||||
@ -2732,7 +2766,8 @@ getTables(int *numTables)
|
||||
"'t'::bool as relhasoids, "
|
||||
"NULL::oid as owning_tab, "
|
||||
"NULL::int4 as owning_col, "
|
||||
"NULL as reltablespace "
|
||||
"NULL as reltablespace, "
|
||||
"NULL as reloptions "
|
||||
"from pg_class c "
|
||||
"where relkind in ('%c', '%c') "
|
||||
"order by oid",
|
||||
@ -2774,6 +2809,7 @@ getTables(int *numTables)
|
||||
i_owning_tab = PQfnumber(res, "owning_tab");
|
||||
i_owning_col = PQfnumber(res, "owning_col");
|
||||
i_reltablespace = PQfnumber(res, "reltablespace");
|
||||
i_reloptions = PQfnumber(res, "reloptions");
|
||||
|
||||
for (i = 0; i < ntups; i++)
|
||||
{
|
||||
@ -2803,6 +2839,7 @@ getTables(int *numTables)
|
||||
tblinfo[i].owning_col = atoi(PQgetvalue(res, i, i_owning_col));
|
||||
}
|
||||
tblinfo[i].reltablespace = strdup(PQgetvalue(res, i, i_reltablespace));
|
||||
tblinfo[i].reloptions = strdup(PQgetvalue(res, i, i_reloptions));
|
||||
|
||||
/* other fields were zeroed above */
|
||||
|
||||
@ -2952,7 +2989,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
i_conname,
|
||||
i_contableoid,
|
||||
i_conoid,
|
||||
i_tablespace;
|
||||
i_tablespace,
|
||||
i_options;
|
||||
int ntups;
|
||||
|
||||
for (i = 0; i < numTables; i++)
|
||||
@ -2981,7 +3019,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
* assume an index won't have more than one internal dependency.
|
||||
*/
|
||||
resetPQExpBuffer(query);
|
||||
if (g_fout->remoteVersion >= 80000)
|
||||
if (g_fout->remoteVersion >= 80200)
|
||||
{
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT t.tableoid, t.oid, "
|
||||
@ -2992,7 +3030,34 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
"c.contype, c.conname, "
|
||||
"c.tableoid as contableoid, "
|
||||
"c.oid as conoid, "
|
||||
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) as tablespace "
|
||||
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) as tablespace, "
|
||||
"array_to_string(t.reloptions, ', ') as options "
|
||||
"FROM pg_catalog.pg_index i "
|
||||
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
|
||||
"LEFT JOIN pg_catalog.pg_depend d "
|
||||
"ON (d.classid = t.tableoid "
|
||||
"AND d.objid = t.oid "
|
||||
"AND d.deptype = 'i') "
|
||||
"LEFT JOIN pg_catalog.pg_constraint c "
|
||||
"ON (d.refclassid = c.tableoid "
|
||||
"AND d.refobjid = c.oid) "
|
||||
"WHERE i.indrelid = '%u'::pg_catalog.oid "
|
||||
"ORDER BY indexname",
|
||||
tbinfo->dobj.catId.oid);
|
||||
}
|
||||
else if (g_fout->remoteVersion >= 80000)
|
||||
{
|
||||
appendPQExpBuffer(query,
|
||||
"SELECT t.tableoid, t.oid, "
|
||||
"t.relname as indexname, "
|
||||
"pg_catalog.pg_get_indexdef(i.indexrelid) as indexdef, "
|
||||
"t.relnatts as indnkeys, "
|
||||
"i.indkey, i.indisclustered, "
|
||||
"c.contype, c.conname, "
|
||||
"c.tableoid as contableoid, "
|
||||
"c.oid as conoid, "
|
||||
"(SELECT spcname FROM pg_catalog.pg_tablespace s WHERE s.oid = t.reltablespace) as tablespace, "
|
||||
"null as options "
|
||||
"FROM pg_catalog.pg_index i "
|
||||
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
|
||||
"LEFT JOIN pg_catalog.pg_depend d "
|
||||
@ -3017,7 +3082,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
"c.contype, c.conname, "
|
||||
"c.tableoid as contableoid, "
|
||||
"c.oid as conoid, "
|
||||
"NULL as tablespace "
|
||||
"NULL as tablespace, "
|
||||
"null as options "
|
||||
"FROM pg_catalog.pg_index i "
|
||||
"JOIN pg_catalog.pg_class t ON (t.oid = i.indexrelid) "
|
||||
"LEFT JOIN pg_catalog.pg_depend d "
|
||||
@ -3044,7 +3110,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
"t.relname as conname, "
|
||||
"0::oid as contableoid, "
|
||||
"t.oid as conoid, "
|
||||
"NULL as tablespace "
|
||||
"NULL as tablespace, "
|
||||
"null as options "
|
||||
"FROM pg_index i, pg_class t "
|
||||
"WHERE t.oid = i.indexrelid "
|
||||
"AND i.indrelid = '%u'::oid "
|
||||
@ -3066,7 +3133,8 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
"t.relname as conname, "
|
||||
"0::oid as contableoid, "
|
||||
"t.oid as conoid, "
|
||||
"NULL as tablespace "
|
||||
"NULL as tablespace, "
|
||||
"null as options "
|
||||
"FROM pg_index i, pg_class t "
|
||||
"WHERE t.oid = i.indexrelid "
|
||||
"AND i.indrelid = '%u'::oid "
|
||||
@ -3091,6 +3159,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
i_contableoid = PQfnumber(res, "contableoid");
|
||||
i_conoid = PQfnumber(res, "conoid");
|
||||
i_tablespace = PQfnumber(res, "tablespace");
|
||||
i_options = PQfnumber(res, "options");
|
||||
|
||||
indxinfo = (IndxInfo *) malloc(ntups * sizeof(IndxInfo));
|
||||
constrinfo = (ConstraintInfo *) malloc(ntups * sizeof(ConstraintInfo));
|
||||
@ -3109,6 +3178,7 @@ getIndexes(TableInfo tblinfo[], int numTables)
|
||||
indxinfo[j].indexdef = strdup(PQgetvalue(res, j, i_indexdef));
|
||||
indxinfo[j].indnkeys = atoi(PQgetvalue(res, j, i_indnkeys));
|
||||
indxinfo[j].tablespace = strdup(PQgetvalue(res, j, i_tablespace));
|
||||
indxinfo[j].options = strdup(PQgetvalue(res, j, i_options));
|
||||
|
||||
/*
|
||||
* In pre-7.4 releases, indkeys may contain more entries than
|
||||
@ -7245,6 +7315,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
|
||||
appendPQExpBuffer(q, ")");
|
||||
}
|
||||
|
||||
if (tbinfo->reloptions && strlen(tbinfo->reloptions) > 0)
|
||||
appendPQExpBuffer(q, "\nWITH (%s)", tbinfo->reloptions);
|
||||
|
||||
appendPQExpBuffer(q, ";\n");
|
||||
|
||||
/* Loop dumping statistics and storage statements */
|
||||
@ -7542,7 +7615,12 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
|
||||
fmtId(attname));
|
||||
}
|
||||
|
||||
appendPQExpBuffer(q, ");\n");
|
||||
appendPQExpBuffer(q, ")");
|
||||
|
||||
if (indxinfo->options && strlen(indxinfo->options) > 0)
|
||||
appendPQExpBuffer(q, " WITH (%s)", indxinfo->options);
|
||||
|
||||
appendPQExpBuffer(q, ";\n");
|
||||
|
||||
/* If the index is clustered, we need to record that. */
|
||||
if (indxinfo->indisclustered)
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.125 2006/03/05 15:58:51 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.126 2006/07/02 02:23:21 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -180,6 +180,7 @@ typedef struct _tableInfo
|
||||
char *relacl;
|
||||
char relkind;
|
||||
char *reltablespace; /* relation tablespace */
|
||||
char *reloptions; /* options specified by WITH (...) */
|
||||
bool hasindex; /* does it have any indexes? */
|
||||
bool hasrules; /* does it have any rules? */
|
||||
bool hasoids; /* does it have OIDs? */
|
||||
@ -247,6 +248,7 @@ typedef struct _indxInfo
|
||||
TableInfo *indextable; /* link to table the index is for */
|
||||
char *indexdef;
|
||||
char *tablespace; /* tablespace in which index is stored */
|
||||
char *options; /* options specified by WITH (...) */
|
||||
int indnkeys;
|
||||
Oid *indkeys;
|
||||
bool indisclustered;
|
||||
|
@ -7,13 +7,14 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/genam.h,v 1.60 2006/05/10 23:18:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/genam.h,v 1.61 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef GENAM_H
|
||||
#define GENAM_H
|
||||
|
||||
#include "access/heapam.h"
|
||||
#include "access/itup.h"
|
||||
#include "access/relscan.h"
|
||||
#include "access/sdir.h"
|
||||
@ -144,4 +145,13 @@ extern SysScanDesc systable_beginscan(Relation heapRelation,
|
||||
extern HeapTuple systable_getnext(SysScanDesc sysscan);
|
||||
extern void systable_endscan(SysScanDesc sysscan);
|
||||
|
||||
|
||||
typedef HeapOption IndexOption;
|
||||
|
||||
extern bytea *genam_option(ArrayType *options,
|
||||
int minFillfactor, int defaultFillfactor);
|
||||
|
||||
#define IndexGetFillFactor(relation) HeapGetFillFactor(relation)
|
||||
#define IndexGetPageFreeSpace(relation) HeapGetPageFreeSpace(relation)
|
||||
|
||||
#endif /* GENAM_H */
|
||||
|
@ -3,7 +3,7 @@
|
||||
* header file for postgres inverted index access method implementation.
|
||||
*
|
||||
* Copyright (c) 2006, PostgreSQL Global Development Group
|
||||
* $PostgreSQL: pgsql/src/include/access/gin.h,v 1.1 2006/05/02 11:28:55 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/gin.h,v 1.2 2006/07/02 02:23:22 momjian Exp $
|
||||
*--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@ -213,6 +213,7 @@ typedef struct ginxlogDeletePage {
|
||||
} ginxlogDeletePage;
|
||||
|
||||
/* ginutil.c */
|
||||
extern Datum ginoption(PG_FUNCTION_ARGS);
|
||||
extern void initGinState( GinState *state, Relation index );
|
||||
extern Buffer GinNewBuffer(Relation index);
|
||||
extern void GinInitBuffer(Buffer b, uint32 f);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.18 2006/06/28 12:00:14 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/gist_private.h,v 1.19 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -202,6 +202,7 @@ typedef struct
|
||||
Relation r;
|
||||
IndexTuple *itup; /* in/out, points to compressed entry */
|
||||
int ituplen; /* length of itup */
|
||||
Size freespace; /* free space to be left */
|
||||
GISTInsertStack *stack;
|
||||
bool needInsertComplete;
|
||||
|
||||
@ -271,8 +272,9 @@ extern Datum gistgetmulti(PG_FUNCTION_ARGS);
|
||||
#define GiSTPageSize \
|
||||
( BLCKSZ - SizeOfPageHeaderData - MAXALIGN(sizeof(GISTPageOpaqueData)) )
|
||||
|
||||
extern Datum gistoption(PG_FUNCTION_ARGS);
|
||||
extern bool gistfitpage(IndexTuple *itvec, int len);
|
||||
extern bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete);
|
||||
extern bool gistnospace(Page page, IndexTuple *itvec, int len, OffsetNumber todelete, Size freespace);
|
||||
extern void gistcheckpage(Relation rel, Buffer buf);
|
||||
extern Buffer gistNewBuffer(Relation r);
|
||||
extern OffsetNumber gistfillbuffer(Relation r, Page page, IndexTuple *itup,
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/hash.h,v 1.69 2006/05/02 22:25:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/hash.h,v 1.70 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* modeled after Margo Seltzer's hash implementation for unix.
|
||||
@ -234,6 +234,7 @@ extern Datum hashmarkpos(PG_FUNCTION_ARGS);
|
||||
extern Datum hashrestrpos(PG_FUNCTION_ARGS);
|
||||
extern Datum hashbulkdelete(PG_FUNCTION_ARGS);
|
||||
extern Datum hashvacuumcleanup(PG_FUNCTION_ARGS);
|
||||
extern Datum hashoption(PG_FUNCTION_ARGS);
|
||||
|
||||
/*
|
||||
* Datatype-specific hash functions in hashfunc.c.
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.112 2006/06/27 02:51:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.113 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -22,6 +22,7 @@
|
||||
#include "nodes/primnodes.h"
|
||||
#include "storage/block.h"
|
||||
#include "storage/lmgr.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/rel.h"
|
||||
#include "utils/tqual.h"
|
||||
|
||||
@ -227,4 +228,32 @@ extern MinimalTuple minimal_tuple_from_heap_tuple(HeapTuple htup);
|
||||
extern HeapTuple heap_addheader(int natts, bool withoid,
|
||||
Size structlen, void *structure);
|
||||
|
||||
extern HeapTuple build_class_tuple(Form_pg_class pgclass, ArrayType *options);
|
||||
|
||||
/*
|
||||
* HeapOption
|
||||
* Internal data of heaps.
|
||||
*/
|
||||
typedef struct HeapOption
|
||||
{
|
||||
int32 vl_len;
|
||||
int fillfactor;
|
||||
} HeapOption;
|
||||
|
||||
extern bytea *heap_option(char relkind, ArrayType *options);
|
||||
|
||||
/*
|
||||
* HeapGetFillFactor
|
||||
* Returns the heap's fillfactor.
|
||||
*/
|
||||
#define HeapGetFillFactor(relation) \
|
||||
(((HeapOption*)(relation)->rd_options)->fillfactor)
|
||||
|
||||
/*
|
||||
* HeapGetPageFreeSpace
|
||||
* Returns the heap's freespace per page in bytes.
|
||||
*/
|
||||
#define HeapGetPageFreeSpace(relation) \
|
||||
(BLCKSZ * (100 - HeapGetFillFactor(relation)) / 100)
|
||||
|
||||
#endif /* HEAPAM_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/hio.h,v 1.30 2006/03/05 15:58:53 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/hio.h,v 1.31 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -19,6 +19,6 @@
|
||||
extern void RelationPutHeapTuple(Relation relation, Buffer buffer,
|
||||
HeapTuple tuple);
|
||||
extern Buffer RelationGetBufferForTuple(Relation relation, Size len,
|
||||
Buffer otherBuffer, bool use_fsm);
|
||||
Buffer otherBuffer, bool use_fsm);
|
||||
|
||||
#endif /* HIO_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.98 2006/05/08 00:00:10 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/access/nbtree.h,v 1.99 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -453,6 +453,7 @@ extern Datum btmarkpos(PG_FUNCTION_ARGS);
|
||||
extern Datum btrestrpos(PG_FUNCTION_ARGS);
|
||||
extern Datum btbulkdelete(PG_FUNCTION_ARGS);
|
||||
extern Datum btvacuumcleanup(PG_FUNCTION_ARGS);
|
||||
extern Datum btoption(PG_FUNCTION_ARGS);
|
||||
|
||||
/*
|
||||
* prototypes for functions in nbtinsert.c
|
||||
|
@ -37,7 +37,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.334 2006/05/24 11:01:39 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.335 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -53,6 +53,6 @@
|
||||
*/
|
||||
|
||||
/* yyyymmddN */
|
||||
#define CATALOG_VERSION_NO 200605241
|
||||
#define CATALOG_VERSION_NO 200607011
|
||||
|
||||
#endif
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.82 2006/06/27 18:35:05 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/heap.h,v 1.83 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -17,6 +17,7 @@
|
||||
#include "catalog/pg_attribute.h"
|
||||
#include "nodes/parsenodes.h"
|
||||
#include "parser/parse_node.h"
|
||||
#include "utils/array.h"
|
||||
#include "utils/rel.h"
|
||||
|
||||
|
||||
@ -54,7 +55,8 @@ extern Oid heap_create_with_catalog(const char *relname,
|
||||
bool oidislocal,
|
||||
int oidinhcount,
|
||||
OnCommitAction oncommit,
|
||||
bool allow_system_table_mods);
|
||||
bool allow_system_table_mods,
|
||||
ArrayType *options);
|
||||
|
||||
extern void heap_drop_with_catalog(Oid relid);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.66 2006/05/10 23:18:39 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/index.h,v 1.67 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -17,6 +17,7 @@
|
||||
#include "access/itup.h"
|
||||
#include "catalog/pg_index.h"
|
||||
#include "nodes/execnodes.h"
|
||||
#include "utils/array.h"
|
||||
|
||||
|
||||
#define DEFAULT_INDEX_TYPE "btree"
|
||||
@ -37,6 +38,7 @@ extern Oid index_create(Oid heapRelationId,
|
||||
Oid accessMethodObjectId,
|
||||
Oid tableSpaceId,
|
||||
Oid *classObjectId,
|
||||
List *options,
|
||||
bool isprimary,
|
||||
bool istoast,
|
||||
bool isconstraint,
|
||||
@ -70,4 +72,6 @@ extern double IndexBuildHeapScan(Relation heapRelation,
|
||||
extern void reindex_index(Oid indexId);
|
||||
extern bool reindex_relation(Oid relid, bool toast_too);
|
||||
|
||||
extern bytea *index_option(RegProcedure amoption, ArrayType *options);
|
||||
|
||||
#endif /* INDEX_H */
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.43 2006/05/24 11:01:39 teodor Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_am.h,v 1.44 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
@ -65,6 +65,7 @@ CATALOG(pg_am,2601)
|
||||
regproc ambulkdelete; /* bulk-delete function */
|
||||
regproc amvacuumcleanup; /* post-VACUUM cleanup function */
|
||||
regproc amcostestimate; /* estimate cost of an indexscan */
|
||||
regproc amoption; /* parse AM-specific parameters */
|
||||
} FormData_pg_am;
|
||||
|
||||
/* ----------------
|
||||
@ -78,7 +79,7 @@ typedef FormData_pg_am *Form_pg_am;
|
||||
* compiler constants for pg_am
|
||||
* ----------------
|
||||
*/
|
||||
#define Natts_pg_am 23
|
||||
#define Natts_pg_am 24
|
||||
#define Anum_pg_am_amname 1
|
||||
#define Anum_pg_am_amstrategies 2
|
||||
#define Anum_pg_am_amsupport 3
|
||||
@ -102,22 +103,23 @@ typedef FormData_pg_am *Form_pg_am;
|
||||
#define Anum_pg_am_ambulkdelete 21
|
||||
#define Anum_pg_am_amvacuumcleanup 22
|
||||
#define Anum_pg_am_amcostestimate 23
|
||||
#define Anum_pg_am_amoption 24
|
||||
|
||||
/* ----------------
|
||||
* initial contents of pg_am
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
DATA(insert OID = 403 ( btree 5 1 1 t t t t f t t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate ));
|
||||
DATA(insert OID = 403 ( btree 5 1 1 t t t t f t t btinsert btbeginscan btgettuple btgetmulti btrescan btendscan btmarkpos btrestrpos btbuild btbulkdelete btvacuumcleanup btcostestimate btoption ));
|
||||
DESCR("b-tree index access method");
|
||||
#define BTREE_AM_OID 403
|
||||
DATA(insert OID = 405 ( hash 1 1 0 f f f f f t f hashinsert hashbeginscan hashgettuple hashgetmulti hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate ));
|
||||
DATA(insert OID = 405 ( hash 1 1 0 f f f f f t f hashinsert hashbeginscan hashgettuple hashgetmulti hashrescan hashendscan hashmarkpos hashrestrpos hashbuild hashbulkdelete hashvacuumcleanup hashcostestimate hashoption ));
|
||||
DESCR("hash index access method");
|
||||
#define HASH_AM_OID 405
|
||||
DATA(insert OID = 783 ( gist 100 7 0 f t t t t t t gistinsert gistbeginscan gistgettuple gistgetmulti gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate ));
|
||||
DATA(insert OID = 783 ( gist 100 7 0 f t t t t t t gistinsert gistbeginscan gistgettuple gistgetmulti gistrescan gistendscan gistmarkpos gistrestrpos gistbuild gistbulkdelete gistvacuumcleanup gistcostestimate gistoption ));
|
||||
DESCR("GiST index access method");
|
||||
#define GIST_AM_OID 783
|
||||
DATA(insert OID = 2742 ( gin 100 4 0 f f f f t t f gininsert ginbeginscan gingettuple gingetmulti ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ));
|
||||
DATA(insert OID = 2742 ( gin 100 4 0 f f f f t t f gininsert ginbeginscan gingettuple gingetmulti ginrescan ginendscan ginmarkpos ginrestrpos ginbuild ginbulkdelete ginvacuumcleanup gincostestimate ginoption ));
|
||||
DESCR("GIN index access method");
|
||||
#define GIN_AM_OID 2742
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.120 2006/03/05 15:58:54 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_attribute.h,v 1.121 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
@ -404,7 +404,8 @@ DATA(insert ( 1249 tableoid 26 0 4 -7 0 -1 -1 t p i t f f t 0));
|
||||
{ 1259, {"relhaspkey"}, 16, -1, 1, 22, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
||||
{ 1259, {"relhasrules"}, 16, -1, 1, 23, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
||||
{ 1259, {"relhassubclass"},16, -1, 1, 24, 0, -1, -1, true, 'p', 'c', true, false, false, true, 0 }, \
|
||||
{ 1259, {"relacl"}, 1034, -1, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
|
||||
{ 1259, {"reloptions"}, 1009, -1, -1, 25, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }, \
|
||||
{ 1259, {"relacl"}, 1034, -1, -1, 26, 1, -1, -1, false, 'x', 'i', false, false, false, true, 0 }
|
||||
|
||||
DATA(insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p i t f f t 0));
|
||||
DATA(insert ( 1259 relnamespace 26 -1 4 2 0 -1 -1 t p i t f f t 0));
|
||||
@ -430,7 +431,8 @@ DATA(insert ( 1259 relhasoids 16 -1 1 21 0 -1 -1 t p c t f f t 0));
|
||||
DATA(insert ( 1259 relhaspkey 16 -1 1 22 0 -1 -1 t p c t f f t 0));
|
||||
DATA(insert ( 1259 relhasrules 16 -1 1 23 0 -1 -1 t p c t f f t 0));
|
||||
DATA(insert ( 1259 relhassubclass 16 -1 1 24 0 -1 -1 t p c t f f t 0));
|
||||
DATA(insert ( 1259 relacl 1034 -1 -1 25 1 -1 -1 f x i f f f t 0));
|
||||
DATA(insert ( 1259 reloptions 1009 -1 -1 25 1 -1 -1 f x i f f f t 0));
|
||||
DATA(insert ( 1259 relacl 1034 -1 -1 26 1 -1 -1 f x i f f f t 0));
|
||||
DATA(insert ( 1259 ctid 27 0 6 -1 0 -1 -1 f p s t f f t 0));
|
||||
DATA(insert ( 1259 oid 26 0 4 -2 0 -1 -1 t p i t f f t 0));
|
||||
DATA(insert ( 1259 xmin 28 0 4 -3 0 -1 -1 t p i t f f t 0));
|
||||
|
@ -8,7 +8,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.92 2006/05/28 02:27:08 alvherre Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_class.h,v 1.93 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* the genbki.sh script reads this file and generates .bki
|
||||
@ -75,9 +75,8 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP
|
||||
bool relhasrules; /* has associated rules */
|
||||
bool relhassubclass; /* has derived classes */
|
||||
|
||||
/*
|
||||
* relacl may or may not be present, see note above!
|
||||
*/
|
||||
/* following fields may or may not be present, see note above! */
|
||||
text reloptions[1]; /* access method specific data */
|
||||
aclitem relacl[1]; /* we declare this just for the catalog */
|
||||
} FormData_pg_class;
|
||||
|
||||
@ -104,7 +103,7 @@ typedef FormData_pg_class *Form_pg_class;
|
||||
* ----------------
|
||||
*/
|
||||
#define Natts_pg_class_fixed 24
|
||||
#define Natts_pg_class 25
|
||||
#define Natts_pg_class 26
|
||||
#define Anum_pg_class_relname 1
|
||||
#define Anum_pg_class_relnamespace 2
|
||||
#define Anum_pg_class_reltype 3
|
||||
@ -129,7 +128,8 @@ typedef FormData_pg_class *Form_pg_class;
|
||||
#define Anum_pg_class_relhaspkey 22
|
||||
#define Anum_pg_class_relhasrules 23
|
||||
#define Anum_pg_class_relhassubclass 24
|
||||
#define Anum_pg_class_relacl 25
|
||||
#define Anum_pg_class_reloptions 25
|
||||
#define Anum_pg_class_relacl 26
|
||||
|
||||
/* ----------------
|
||||
* initial contents of pg_class
|
||||
@ -139,13 +139,13 @@ typedef FormData_pg_class *Form_pg_class;
|
||||
* ----------------
|
||||
*/
|
||||
|
||||
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ ));
|
||||
DATA(insert OID = 1247 ( pg_type PGNSP 71 PGUID 0 1247 0 0 0 0 0 f f r 23 0 0 0 0 0 t f f f _null_ _null_ ));
|
||||
DESCR("");
|
||||
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f _null_ ));
|
||||
DATA(insert OID = 1249 ( pg_attribute PGNSP 75 PGUID 0 1249 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f f _null_ _null_ ));
|
||||
DESCR("");
|
||||
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 18 0 0 0 0 0 t f f f _null_ ));
|
||||
DATA(insert OID = 1255 ( pg_proc PGNSP 81 PGUID 0 1255 0 0 0 0 0 f f r 18 0 0 0 0 0 t f f f _null_ _null_ ));
|
||||
DESCR("");
|
||||
DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 0 f f r 25 0 0 0 0 0 t f f f _null_ ));
|
||||
DATA(insert OID = 1259 ( pg_class PGNSP 83 PGUID 0 1259 0 0 0 0 0 f f r 26 0 0 0 0 0 t f f f _null_ _null_ ));
|
||||
DESCR("");
|
||||
|
||||
#define RELKIND_INDEX 'i' /* secondary index */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.413 2006/06/06 17:59:57 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.414 2006/07/02 02:23:22 momjian Exp $
|
||||
*
|
||||
* NOTES
|
||||
* The script catalog/genbki.sh reads this file and generates .bki
|
||||
@ -680,6 +680,8 @@ DATA(insert OID = 972 ( btvacuumcleanup PGNSP PGUID 12 f f t f v 2 2281 "2281
|
||||
DESCR("btree(internal)");
|
||||
DATA(insert OID = 1268 ( btcostestimate PGNSP PGUID 12 f f t f v 8 2278 "2281 2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ btcostestimate - _null_ ));
|
||||
DESCR("btree(internal)");
|
||||
DATA(insert OID = 2785 ( btoption PGNSP PGUID 12 f f t f v 1 2281 "2281" _null_ _null_ _null_ btoption - _null_ ));
|
||||
DESCR("btree(internal)");
|
||||
|
||||
DATA(insert OID = 339 ( poly_same PGNSP PGUID 12 f f t f i 2 16 "604 604" _null_ _null_ _null_ poly_same - _null_ ));
|
||||
DESCR("same as?");
|
||||
@ -797,6 +799,8 @@ DATA(insert OID = 425 ( hashvacuumcleanup PGNSP PGUID 12 f f t f v 2 2281 "2281
|
||||
DESCR("hash(internal)");
|
||||
DATA(insert OID = 438 ( hashcostestimate PGNSP PGUID 12 f f t f v 8 2278 "2281 2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ hashcostestimate - _null_ ));
|
||||
DESCR("hash(internal)");
|
||||
DATA(insert OID = 2786 ( hashoption PGNSP PGUID 12 f f t f v 1 2281 "2281" _null_ _null_ _null_ hashoption - _null_ ));
|
||||
DESCR("hash(internal)");
|
||||
|
||||
DATA(insert OID = 449 ( hashint2 PGNSP PGUID 12 f f t f i 1 23 "21" _null_ _null_ _null_ hashint2 - _null_ ));
|
||||
DESCR("hash");
|
||||
@ -1063,6 +1067,8 @@ DATA(insert OID = 2561 ( gistvacuumcleanup PGNSP PGUID 12 f f t f v 2 2281 "2
|
||||
DESCR("gist(internal)");
|
||||
DATA(insert OID = 772 ( gistcostestimate PGNSP PGUID 12 f f t f v 8 2278 "2281 2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ gistcostestimate - _null_ ));
|
||||
DESCR("gist(internal)");
|
||||
DATA(insert OID = 2787 ( gistoption PGNSP PGUID 12 f f t f v 1 2281 "2281" _null_ _null_ _null_ gistoption - _null_ ));
|
||||
DESCR("gist(internal)");
|
||||
|
||||
DATA(insert OID = 784 ( tintervaleq PGNSP PGUID 12 f f t f i 2 16 "704 704" _null_ _null_ _null_ tintervaleq - _null_ ));
|
||||
DESCR("equal");
|
||||
@ -3849,6 +3855,8 @@ DATA(insert OID = 2740 ( ginvacuumcleanup PGNSP PGUID 12 f f t f v 2 2281 "2281
|
||||
DESCR("gin(internal)");
|
||||
DATA(insert OID = 2741 ( gincostestimate PGNSP PGUID 12 f f t f v 8 2278 "2281 2281 2281 2281 2281 2281 2281 2281" _null_ _null_ _null_ gincostestimate - _null_ ));
|
||||
DESCR("gin(internal)");
|
||||
DATA(insert OID = 2788 ( ginoption PGNSP PGUID 12 f f t f v 1 2281 "2281" _null_ _null_ _null_ ginoption - _null_ ));
|
||||
DESCR("gin(internal)");
|
||||
|
||||
/* GIN array support */
|
||||
DATA(insert OID = 2743 ( ginarrayextract PGNSP PGUID 12 f f t f i 2 2281 "2277 2281" _null_ _null_ _null_ ginarrayextract - _null_ ));
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.72 2006/04/15 17:45:41 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.73 2006/07/02 02:23:23 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -26,6 +26,7 @@ extern void DefineIndex(RangeVar *heapRelation,
|
||||
List *attributeList,
|
||||
Expr *predicate,
|
||||
List *rangetable,
|
||||
List *options,
|
||||
bool unique,
|
||||
bool primary,
|
||||
bool isconstraint,
|
||||
@ -95,4 +96,6 @@ extern List *defGetQualifiedName(DefElem *def);
|
||||
extern TypeName *defGetTypeName(DefElem *def);
|
||||
extern int defGetTypeLength(DefElem *def);
|
||||
|
||||
extern DefElem *defWithOids(bool value);
|
||||
|
||||
#endif /* DEFREM_H */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.313 2006/07/02 01:58:36 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.314 2006/07/02 02:23:23 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -93,6 +93,7 @@ typedef struct Query
|
||||
|
||||
RangeVar *into; /* target relation for SELECT INTO */
|
||||
bool intoHasOids; /* should target relation contain OIDs? */
|
||||
List *intoOptions; /* options passed by WITH */
|
||||
OnCommitAction intoOnCommit; /* what do we do at COMMIT? */
|
||||
char *intoTableSpaceName; /* table space to use, or NULL */
|
||||
|
||||
@ -693,15 +694,6 @@ typedef enum SetOperation
|
||||
SETOP_EXCEPT
|
||||
} SetOperation;
|
||||
|
||||
typedef enum ContainsOids
|
||||
{
|
||||
MUST_HAVE_OIDS, /* WITH OIDS explicitly specified */
|
||||
MUST_NOT_HAVE_OIDS, /* WITHOUT OIDS explicitly specified */
|
||||
DEFAULT_OIDS /* neither specified; use the default, which
|
||||
* is the value of the default_with_oids GUC
|
||||
* var */
|
||||
} ContainsOids;
|
||||
|
||||
typedef struct SelectStmt
|
||||
{
|
||||
NodeTag type;
|
||||
@ -709,14 +701,14 @@ typedef struct SelectStmt
|
||||
/*
|
||||
* These fields are used only in "leaf" SelectStmts.
|
||||
*
|
||||
* into, intoColNames, intoHasOids, intoOnCommit, and
|
||||
* into, intoColNames, intoOptions, intoOnCommit, and
|
||||
* intoTableSpaceName are a kluge; they belong somewhere else...
|
||||
*/
|
||||
List *distinctClause; /* NULL, list of DISTINCT ON exprs, or
|
||||
* lcons(NIL,NIL) for all (SELECT DISTINCT) */
|
||||
RangeVar *into; /* target table (for select into table) */
|
||||
List *intoColNames; /* column names for into table */
|
||||
ContainsOids intoHasOids; /* should target table have OIDs? */
|
||||
List *intoOptions; /* options passed by WITH */
|
||||
OnCommitAction intoOnCommit; /* what do we do at COMMIT? */
|
||||
char *intoTableSpaceName; /* table space to use, or NULL */
|
||||
List *targetList; /* the target list (of ResTarget) */
|
||||
@ -869,6 +861,7 @@ typedef enum AlterTableType
|
||||
AT_DropCluster, /* SET WITHOUT CLUSTER */
|
||||
AT_DropOids, /* SET WITHOUT OIDS */
|
||||
AT_SetTableSpace, /* SET TABLESPACE */
|
||||
AT_SetOptions, /* SET (...) -- AM specific parameters */
|
||||
AT_EnableTrig, /* ENABLE TRIGGER name */
|
||||
AT_DisableTrig, /* DISABLE TRIGGER name */
|
||||
AT_EnableTrigAll, /* ENABLE TRIGGER ALL */
|
||||
@ -1024,7 +1017,7 @@ typedef struct CreateStmt
|
||||
List *inhRelations; /* relations to inherit from (list of
|
||||
* inhRelation) */
|
||||
List *constraints; /* constraints (list of Constraint nodes) */
|
||||
ContainsOids hasoids; /* should it have OIDs? */
|
||||
List *options; /* options passed by WITH */
|
||||
OnCommitAction oncommit; /* what do we do at COMMIT? */
|
||||
char *tablespacename; /* table space to use, or NULL */
|
||||
} CreateStmt;
|
||||
@ -1082,6 +1075,7 @@ typedef struct Constraint
|
||||
Node *raw_expr; /* expr, as untransformed parse tree */
|
||||
char *cooked_expr; /* expr, as nodeToString representation */
|
||||
List *keys; /* String nodes naming referenced column(s) */
|
||||
List *options; /* options passed by WITH */
|
||||
char *indexspace; /* index tablespace for PKEY/UNIQUE
|
||||
* constraints; NULL for default */
|
||||
} Constraint;
|
||||
@ -1435,6 +1429,7 @@ typedef struct IndexStmt
|
||||
char *accessMethod; /* name of access method (eg. btree) */
|
||||
char *tableSpace; /* tablespace, or NULL to use parent's */
|
||||
List *indexParams; /* a list of IndexElem */
|
||||
List *options; /* options passed by WITH */
|
||||
Node *whereClause; /* qualification (partial-index predicate) */
|
||||
List *rangetable; /* range table for qual and/or expressions,
|
||||
* filled in by transformStmt() */
|
||||
@ -1891,8 +1886,8 @@ typedef struct ExecuteStmt
|
||||
NodeTag type;
|
||||
char *name; /* The name of the plan to execute */
|
||||
RangeVar *into; /* Optional table to store results in */
|
||||
ContainsOids into_contains_oids; /* Should it have OIDs? */
|
||||
bool into_has_oids; /* Merge GUC info with user input */
|
||||
List *intoOptions; /* options passed by WITH */
|
||||
OnCommitAction into_on_commit; /* What do we do at COMMIT? */
|
||||
char *into_tbl_space; /* Tablespace to use, or NULL */
|
||||
List *params; /* Values to assign to parameters */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.44 2006/03/05 15:58:57 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/include/parser/parse_clause.h,v 1.45 2006/07/02 02:23:23 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -15,12 +15,17 @@
|
||||
#define PARSE_CLAUSE_H
|
||||
|
||||
#include "parser/parse_node.h"
|
||||
#include "utils/array.h"
|
||||
|
||||
extern void transformFromClause(ParseState *pstate, List *frmList);
|
||||
extern int setTargetTable(ParseState *pstate, RangeVar *relation,
|
||||
bool inh, bool alsoSource, AclMode requiredPerms);
|
||||
extern bool interpretInhOption(InhOption inhOpt);
|
||||
extern bool interpretOidsOption(ContainsOids opt);
|
||||
extern bool interpretOidsOption(List *options);
|
||||
|
||||
extern ArrayType *OptionBuild(ArrayType *array, List *list);
|
||||
extern void OptionParse(ArrayType *options, Size num, DefElem kwds[],
|
||||
bool strict);
|
||||
|
||||
extern Node *transformWhereClause(ParseState *pstate, Node *clause,
|
||||
const char *constructName);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.89 2006/04/25 22:46:05 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/include/utils/rel.h,v 1.90 2006/07/02 02:23:23 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -115,6 +115,7 @@ typedef struct RelationAmInfo
|
||||
FmgrInfo ambulkdelete;
|
||||
FmgrInfo amvacuumcleanup;
|
||||
FmgrInfo amcostestimate;
|
||||
FmgrInfo amoption;
|
||||
} RelationAmInfo;
|
||||
|
||||
|
||||
@ -142,8 +143,14 @@ typedef struct RelationData
|
||||
* survived into; or zero if the rel was not created in the current top
|
||||
* transaction. This should be relied on only for optimization purposes;
|
||||
* it is possible for new-ness to be "forgotten" (eg, after CLUSTER).
|
||||
*
|
||||
* rd_options and rd_amcache are alike, but different in terms of
|
||||
* lifetime. Invalidation of rd_options is at the change of pg_class
|
||||
* and of rd_amcache is at the change of AM's metapages. Also, rd_options
|
||||
* is serialized in the relcache init file, but rd_amcache is not.
|
||||
*/
|
||||
Form_pg_class rd_rel; /* RELATION tuple */
|
||||
bytea *rd_options; /* parsed rd_rel->reloptions */
|
||||
TupleDesc rd_att; /* tuple descriptor */
|
||||
Oid rd_id; /* relation's object id */
|
||||
List *rd_indexlist; /* list of OIDs of indexes on relation */
|
||||
|
Loading…
Reference in New Issue
Block a user