mirror of
https://github.com/postgres/postgres.git
synced 2025-09-08 00:47:37 +03:00
Support USING INDEX TABLESPACE clause for PRIMARY KEY and UNIQUE
constraints. Christopher Kings-Lynne.
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.288 2004/07/12 05:37:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.289 2004/08/02 04:26:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1485,6 +1485,7 @@ _copyConstraint(Constraint *from)
|
||||
COPY_NODE_FIELD(raw_expr);
|
||||
COPY_STRING_FIELD(cooked_expr);
|
||||
COPY_NODE_FIELD(keys);
|
||||
COPY_STRING_FIELD(indexspace);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.227 2004/07/12 05:37:24 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.228 2004/08/02 04:26:05 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1611,6 +1611,7 @@ _equalConstraint(Constraint *a, Constraint *b)
|
||||
COMPARE_NODE_FIELD(raw_expr);
|
||||
COMPARE_STRING_FIELD(cooked_expr);
|
||||
COMPARE_NODE_FIELD(keys);
|
||||
COMPARE_STRING_FIELD(indexspace);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.240 2004/06/18 06:13:28 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.241 2004/08/02 04:26:05 tgl Exp $
|
||||
*
|
||||
* NOTES
|
||||
* Every node type that can appear in stored rules' parsetrees *must*
|
||||
@@ -1537,6 +1537,13 @@ _outConstraint(StringInfo str, Constraint *node)
|
||||
case CONSTR_PRIMARY:
|
||||
appendStringInfo(str, "PRIMARY_KEY");
|
||||
WRITE_NODE_FIELD(keys);
|
||||
WRITE_STRING_FIELD(indexspace);
|
||||
break;
|
||||
|
||||
case CONSTR_UNIQUE:
|
||||
appendStringInfo(str, "UNIQUE");
|
||||
WRITE_NODE_FIELD(keys);
|
||||
WRITE_STRING_FIELD(indexspace);
|
||||
break;
|
||||
|
||||
case CONSTR_CHECK:
|
||||
@@ -1555,11 +1562,6 @@ _outConstraint(StringInfo str, Constraint *node)
|
||||
appendStringInfo(str, "NOT_NULL");
|
||||
break;
|
||||
|
||||
case CONSTR_UNIQUE:
|
||||
appendStringInfo(str, "UNIQUE");
|
||||
WRITE_NODE_FIELD(keys);
|
||||
break;
|
||||
|
||||
default:
|
||||
appendStringInfo(str, "<unrecognized_constraint>");
|
||||
break;
|
||||
|
@@ -6,7 +6,7 @@
|
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.307 2004/07/12 05:37:44 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.308 2004/08/02 04:26:29 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1199,7 +1199,7 @@ transformIndexConstraints(ParseState *pstate, CreateStmtContext *cxt)
|
||||
|
||||
index->relation = cxt->relation;
|
||||
index->accessMethod = DEFAULT_INDEX_TYPE;
|
||||
index->tableSpace = NULL;
|
||||
index->tableSpace = constraint->indexspace;
|
||||
index->indexParams = NIL;
|
||||
index->whereClause = NULL;
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.468 2004/07/27 05:10:55 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.469 2004/08/02 04:26:35 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@@ -320,7 +320,7 @@ static void doNegateFloat(Value *v);
|
||||
|
||||
%type <list> constraints_set_list
|
||||
%type <boolean> constraints_set_mode
|
||||
%type <str> OptTableSpace OptTableSpaceOwner
|
||||
%type <str> OptTableSpace OptConsTableSpace OptTableSpaceOwner
|
||||
|
||||
|
||||
/*
|
||||
@@ -1609,6 +1609,7 @@ ColConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = NULL;
|
||||
n->indexspace = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| NULL_P
|
||||
@@ -1619,9 +1620,10 @@ ColConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = NULL;
|
||||
n->indexspace = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| UNIQUE
|
||||
| UNIQUE OptConsTableSpace
|
||||
{
|
||||
Constraint *n = makeNode(Constraint);
|
||||
n->contype = CONSTR_UNIQUE;
|
||||
@@ -1629,9 +1631,10 @@ ColConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = NULL;
|
||||
n->indexspace = $2;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| PRIMARY KEY
|
||||
| PRIMARY KEY OptConsTableSpace
|
||||
{
|
||||
Constraint *n = makeNode(Constraint);
|
||||
n->contype = CONSTR_PRIMARY;
|
||||
@@ -1639,6 +1642,7 @@ ColConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = NULL;
|
||||
n->indexspace = $3;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| CHECK '(' a_expr ')'
|
||||
@@ -1649,6 +1653,7 @@ ColConstraintElem:
|
||||
n->raw_expr = $3;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = NULL;
|
||||
n->indexspace = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| DEFAULT b_expr
|
||||
@@ -1667,6 +1672,7 @@ ColConstraintElem:
|
||||
}
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = NULL;
|
||||
n->indexspace = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| REFERENCES qualified_name opt_column_list key_match key_actions
|
||||
@@ -1787,9 +1793,10 @@ ConstraintElem:
|
||||
n->name = NULL;
|
||||
n->raw_expr = $3;
|
||||
n->cooked_expr = NULL;
|
||||
n->indexspace = NULL;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| UNIQUE '(' columnList ')'
|
||||
| UNIQUE '(' columnList ')' OptConsTableSpace
|
||||
{
|
||||
Constraint *n = makeNode(Constraint);
|
||||
n->contype = CONSTR_UNIQUE;
|
||||
@@ -1797,9 +1804,10 @@ ConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = $3;
|
||||
n->indexspace = $5;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| PRIMARY KEY '(' columnList ')'
|
||||
| PRIMARY KEY '(' columnList ')' OptConsTableSpace
|
||||
{
|
||||
Constraint *n = makeNode(Constraint);
|
||||
n->contype = CONSTR_PRIMARY;
|
||||
@@ -1807,6 +1815,7 @@ ConstraintElem:
|
||||
n->raw_expr = NULL;
|
||||
n->cooked_expr = NULL;
|
||||
n->keys = $4;
|
||||
n->indexspace = $6;
|
||||
$$ = (Node *)n;
|
||||
}
|
||||
| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name
|
||||
@@ -1916,6 +1925,10 @@ OptTableSpace: TABLESPACE name { $$ = $2; }
|
||||
| /*EMPTY*/ { $$ = NULL; }
|
||||
;
|
||||
|
||||
OptConsTableSpace: USING INDEX TABLESPACE name { $$ = $4; }
|
||||
| /*EMPTY*/ { $$ = NULL; }
|
||||
;
|
||||
|
||||
|
||||
/*
|
||||
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for
|
||||
|
@@ -3,7 +3,7 @@
|
||||
* back to source text
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.175 2004/07/06 04:50:21 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.176 2004/08/02 04:27:15 tgl Exp $
|
||||
*
|
||||
* This software is copyrighted by Jan Wieck - Hamburg.
|
||||
*
|
||||
@@ -162,6 +162,7 @@ static char *pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
|
||||
int prettyFlags);
|
||||
static char *pg_get_expr_worker(text *expr, Oid relid, char *relname,
|
||||
int prettyFlags);
|
||||
static Oid get_constraint_index(Oid constraintRelOid, Oid constraintOid);
|
||||
static void make_ruledef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
|
||||
int prettyFlags);
|
||||
static void make_viewdef(StringInfo buf, HeapTuple ruletup, TupleDesc rulettc,
|
||||
@@ -1015,6 +1016,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
|
||||
{
|
||||
Datum val;
|
||||
bool isnull;
|
||||
Oid indexOid;
|
||||
|
||||
/* Start off the constraint definition */
|
||||
if (conForm->contype == CONSTRAINT_PRIMARY)
|
||||
@@ -1033,6 +1035,29 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
|
||||
|
||||
appendStringInfo(&buf, ")");
|
||||
|
||||
/* Add TABLESPACE if it's not default */
|
||||
indexOid = get_constraint_index(RelationGetRelid(conDesc),
|
||||
constraintId);
|
||||
if (OidIsValid(indexOid))
|
||||
{
|
||||
Oid reltablespace;
|
||||
Oid indtablespace;
|
||||
|
||||
reltablespace = get_rel_tablespace(conForm->conrelid);
|
||||
indtablespace = get_rel_tablespace(indexOid);
|
||||
if (OidIsValid(indtablespace) &&
|
||||
indtablespace != reltablespace)
|
||||
{
|
||||
char *spcname = get_tablespace_name(indtablespace);
|
||||
|
||||
if (spcname) /* just paranoia... */
|
||||
{
|
||||
appendStringInfo(&buf, " USING INDEX TABLESPACE %s",
|
||||
quote_identifier(spcname));
|
||||
pfree(spcname);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CONSTRAINT_CHECK:
|
||||
@@ -1343,6 +1368,67 @@ pg_get_serial_sequence(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
/*
|
||||
* get_constraint_index
|
||||
* Given the OID of a unique or primary-key constraint,
|
||||
* look up the OID of the underlying index.
|
||||
*
|
||||
* We make the caller pass in the OID of pg_constraint, too, simply because
|
||||
* it's probably got it at hand already.
|
||||
*
|
||||
* Returns InvalidOid if index can't be found.
|
||||
*/
|
||||
static Oid
|
||||
get_constraint_index(Oid constraintRelOid, Oid constraintOid)
|
||||
{
|
||||
Oid result = InvalidOid;
|
||||
Relation depRel;
|
||||
ScanKeyData key[3];
|
||||
SysScanDesc scan;
|
||||
HeapTuple tup;
|
||||
|
||||
/* Search the dependency table for the dependent index */
|
||||
depRel = heap_openr(DependRelationName, AccessShareLock);
|
||||
|
||||
ScanKeyInit(&key[0],
|
||||
Anum_pg_depend_refclassid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(constraintRelOid));
|
||||
ScanKeyInit(&key[1],
|
||||
Anum_pg_depend_refobjid,
|
||||
BTEqualStrategyNumber, F_OIDEQ,
|
||||
ObjectIdGetDatum(constraintOid));
|
||||
ScanKeyInit(&key[2],
|
||||
Anum_pg_depend_refobjsubid,
|
||||
BTEqualStrategyNumber, F_INT4EQ,
|
||||
Int32GetDatum(0));
|
||||
|
||||
scan = systable_beginscan(depRel, DependReferenceIndex, true,
|
||||
SnapshotNow, 3, key);
|
||||
|
||||
while (HeapTupleIsValid(tup = systable_getnext(scan)))
|
||||
{
|
||||
Form_pg_depend deprec = (Form_pg_depend) GETSTRUCT(tup);
|
||||
|
||||
/*
|
||||
* We assume any internal dependency of a relation on the constraint
|
||||
* must be what we are looking for.
|
||||
*/
|
||||
if (deprec->classid == RelOid_pg_class &&
|
||||
deprec->objsubid == 0 &&
|
||||
deprec->deptype == DEPENDENCY_INTERNAL)
|
||||
{
|
||||
result = deprec->objid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
systable_endscan(scan);
|
||||
heap_close(depRel, AccessShareLock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* ----------
|
||||
* deparse_expression - General utility for deparsing expressions
|
||||
|
Reference in New Issue
Block a user