Use heap_formtuple not heap_addheader to construct pg_index tuples.
heap_addheader is wrong because it doesn't cope with varlena fields, notably indpred.
This commit is contained in:
parent
cb253de21a
commit
d2d0f42040
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.200 2002/09/23 00:42:48 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.201 2002/09/27 15:05:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* INTERFACE ROUTINES
|
* INTERFACE ROUTINES
|
||||||
@ -420,56 +420,44 @@ UpdateIndexRelation(Oid indexoid,
|
|||||||
Oid *classOids,
|
Oid *classOids,
|
||||||
bool primary)
|
bool primary)
|
||||||
{
|
{
|
||||||
Form_pg_index indexForm;
|
int16 indkey[INDEX_MAX_KEYS];
|
||||||
char *predString;
|
Oid indclass[INDEX_MAX_KEYS];
|
||||||
text *predText;
|
Datum predDatum;
|
||||||
int predLen,
|
Datum values[Natts_pg_index];
|
||||||
itupLen;
|
char nulls[Natts_pg_index];
|
||||||
Relation pg_index;
|
Relation pg_index;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* allocate a Form_pg_index big enough to hold the index-predicate (if
|
* Copy the index key and opclass info into zero-filled vectors
|
||||||
* any) in string form
|
*
|
||||||
|
* (zero filling is essential 'cause we don't store the number of
|
||||||
|
* index columns explicitly in pg_index, which is pretty grotty...)
|
||||||
|
*/
|
||||||
|
MemSet(indkey, 0, sizeof(indkey));
|
||||||
|
for (i = 0; i < indexInfo->ii_NumKeyAttrs; i++)
|
||||||
|
indkey[i] = indexInfo->ii_KeyAttrNumbers[i];
|
||||||
|
|
||||||
|
MemSet(indclass, 0, sizeof(indclass));
|
||||||
|
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
|
||||||
|
indclass[i] = classOids[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert the index-predicate (if any) to a text datum
|
||||||
*/
|
*/
|
||||||
if (indexInfo->ii_Predicate != NIL)
|
if (indexInfo->ii_Predicate != NIL)
|
||||||
{
|
{
|
||||||
|
char *predString;
|
||||||
|
|
||||||
predString = nodeToString(indexInfo->ii_Predicate);
|
predString = nodeToString(indexInfo->ii_Predicate);
|
||||||
predText = DatumGetTextP(DirectFunctionCall1(textin,
|
predDatum = DirectFunctionCall1(textin,
|
||||||
CStringGetDatum(predString)));
|
CStringGetDatum(predString));
|
||||||
pfree(predString);
|
pfree(predString);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
predText = DatumGetTextP(DirectFunctionCall1(textin,
|
predDatum = DirectFunctionCall1(textin,
|
||||||
CStringGetDatum("")));
|
CStringGetDatum(""));
|
||||||
|
|
||||||
predLen = VARSIZE(predText);
|
|
||||||
itupLen = predLen + sizeof(FormData_pg_index);
|
|
||||||
indexForm = (Form_pg_index) palloc(itupLen);
|
|
||||||
MemSet(indexForm, 0, sizeof(FormData_pg_index));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* store information into the index tuple form
|
|
||||||
*/
|
|
||||||
indexForm->indexrelid = indexoid;
|
|
||||||
indexForm->indrelid = heapoid;
|
|
||||||
indexForm->indproc = indexInfo->ii_FuncOid;
|
|
||||||
indexForm->indisclustered = false; /* not clustered, yet */
|
|
||||||
indexForm->indisunique = indexInfo->ii_Unique;
|
|
||||||
indexForm->indisprimary = primary;
|
|
||||||
memcpy((char *) &indexForm->indpred, (char *) predText, predLen);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* copy index key and op class information
|
|
||||||
*
|
|
||||||
* We zeroed the extra slots (if any) above --- that's essential.
|
|
||||||
*/
|
|
||||||
for (i = 0; i < indexInfo->ii_NumKeyAttrs; i++)
|
|
||||||
indexForm->indkey[i] = indexInfo->ii_KeyAttrNumbers[i];
|
|
||||||
|
|
||||||
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
|
|
||||||
indexForm->indclass[i] = classOids[i];
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* open the system catalog index relation
|
* open the system catalog index relation
|
||||||
@ -477,12 +465,22 @@ UpdateIndexRelation(Oid indexoid,
|
|||||||
pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
|
pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* form a tuple to insert into pg_index
|
* Build a pg_index tuple
|
||||||
*/
|
*/
|
||||||
tuple = heap_addheader(Natts_pg_index,
|
MemSet(nulls, ' ', sizeof(nulls));
|
||||||
false,
|
|
||||||
itupLen,
|
values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
|
||||||
(void *) indexForm);
|
values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
|
||||||
|
values[Anum_pg_index_indproc - 1] = ObjectIdGetDatum(indexInfo->ii_FuncOid);
|
||||||
|
values[Anum_pg_index_indkey - 1] = PointerGetDatum(indkey);
|
||||||
|
values[Anum_pg_index_indclass - 1] = PointerGetDatum(indclass);
|
||||||
|
values[Anum_pg_index_indisclustered - 1] = BoolGetDatum(false);
|
||||||
|
values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
|
||||||
|
values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
|
||||||
|
values[Anum_pg_index_indreference - 1] = ObjectIdGetDatum(InvalidOid);
|
||||||
|
values[Anum_pg_index_indpred - 1] = predDatum;
|
||||||
|
|
||||||
|
tuple = heap_formtuple(RelationGetDescr(pg_index), values, nulls);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* insert the tuple into the pg_index catalog
|
* insert the tuple into the pg_index catalog
|
||||||
@ -496,8 +494,6 @@ UpdateIndexRelation(Oid indexoid,
|
|||||||
* close the relation and free the tuple
|
* close the relation and free the tuple
|
||||||
*/
|
*/
|
||||||
heap_close(pg_index, RowExclusiveLock);
|
heap_close(pg_index, RowExclusiveLock);
|
||||||
pfree(predText);
|
|
||||||
pfree(indexForm);
|
|
||||||
heap_freetuple(tuple);
|
heap_freetuple(tuple);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user