Skip to content

Commit d2d0f42

Browse files
committed
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.
1 parent cb253de commit d2d0f42

File tree

1 file changed

+42
-46
lines changed

1 file changed

+42
-46
lines changed

src/backend/catalog/index.c

Lines changed: 42 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.200 2002/09/23 00:42:48 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.201 2002/09/27 15:05:23 tgl Exp $
1212
*
1313
*
1414
* INTERFACE ROUTINES
@@ -420,69 +420,67 @@ UpdateIndexRelation(Oid indexoid,
420420
Oid *classOids,
421421
bool primary)
422422
{
423-
Form_pg_index indexForm;
424-
char *predString;
425-
text *predText;
426-
int predLen,
427-
itupLen;
423+
int16 indkey[INDEX_MAX_KEYS];
424+
Oid indclass[INDEX_MAX_KEYS];
425+
Datum predDatum;
426+
Datum values[Natts_pg_index];
427+
char nulls[Natts_pg_index];
428428
Relation pg_index;
429429
HeapTuple tuple;
430430
int i;
431431

432432
/*
433-
* allocate a Form_pg_index big enough to hold the index-predicate (if
434-
* any) in string form
433+
* Copy the index key and opclass info into zero-filled vectors
434+
*
435+
* (zero filling is essential 'cause we don't store the number of
436+
* index columns explicitly in pg_index, which is pretty grotty...)
437+
*/
438+
MemSet(indkey, 0, sizeof(indkey));
439+
for (i = 0; i < indexInfo->ii_NumKeyAttrs; i++)
440+
indkey[i] = indexInfo->ii_KeyAttrNumbers[i];
441+
442+
MemSet(indclass, 0, sizeof(indclass));
443+
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
444+
indclass[i] = classOids[i];
445+
446+
/*
447+
* Convert the index-predicate (if any) to a text datum
435448
*/
436449
if (indexInfo->ii_Predicate != NIL)
437450
{
451+
char *predString;
452+
438453
predString = nodeToString(indexInfo->ii_Predicate);
439-
predText = DatumGetTextP(DirectFunctionCall1(textin,
440-
CStringGetDatum(predString)));
454+
predDatum = DirectFunctionCall1(textin,
455+
CStringGetDatum(predString));
441456
pfree(predString);
442457
}
443458
else
444-
predText = DatumGetTextP(DirectFunctionCall1(textin,
445-
CStringGetDatum("")));
446-
447-
predLen = VARSIZE(predText);
448-
itupLen = predLen + sizeof(FormData_pg_index);
449-
indexForm = (Form_pg_index) palloc(itupLen);
450-
MemSet(indexForm, 0, sizeof(FormData_pg_index));
451-
452-
/*
453-
* store information into the index tuple form
454-
*/
455-
indexForm->indexrelid = indexoid;
456-
indexForm->indrelid = heapoid;
457-
indexForm->indproc = indexInfo->ii_FuncOid;
458-
indexForm->indisclustered = false; /* not clustered, yet */
459-
indexForm->indisunique = indexInfo->ii_Unique;
460-
indexForm->indisprimary = primary;
461-
memcpy((char *) &indexForm->indpred, (char *) predText, predLen);
462-
463-
/*
464-
* copy index key and op class information
465-
*
466-
* We zeroed the extra slots (if any) above --- that's essential.
467-
*/
468-
for (i = 0; i < indexInfo->ii_NumKeyAttrs; i++)
469-
indexForm->indkey[i] = indexInfo->ii_KeyAttrNumbers[i];
470-
471-
for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
472-
indexForm->indclass[i] = classOids[i];
459+
predDatum = DirectFunctionCall1(textin,
460+
CStringGetDatum(""));
473461

474462
/*
475463
* open the system catalog index relation
476464
*/
477465
pg_index = heap_openr(IndexRelationName, RowExclusiveLock);
478466

479467
/*
480-
* form a tuple to insert into pg_index
468+
* Build a pg_index tuple
481469
*/
482-
tuple = heap_addheader(Natts_pg_index,
483-
false,
484-
itupLen,
485-
(void *) indexForm);
470+
MemSet(nulls, ' ', sizeof(nulls));
471+
472+
values[Anum_pg_index_indexrelid - 1] = ObjectIdGetDatum(indexoid);
473+
values[Anum_pg_index_indrelid - 1] = ObjectIdGetDatum(heapoid);
474+
values[Anum_pg_index_indproc - 1] = ObjectIdGetDatum(indexInfo->ii_FuncOid);
475+
values[Anum_pg_index_indkey - 1] = PointerGetDatum(indkey);
476+
values[Anum_pg_index_indclass - 1] = PointerGetDatum(indclass);
477+
values[Anum_pg_index_indisclustered - 1] = BoolGetDatum(false);
478+
values[Anum_pg_index_indisunique - 1] = BoolGetDatum(indexInfo->ii_Unique);
479+
values[Anum_pg_index_indisprimary - 1] = BoolGetDatum(primary);
480+
values[Anum_pg_index_indreference - 1] = ObjectIdGetDatum(InvalidOid);
481+
values[Anum_pg_index_indpred - 1] = predDatum;
482+
483+
tuple = heap_formtuple(RelationGetDescr(pg_index), values, nulls);
486484

487485
/*
488486
* insert the tuple into the pg_index catalog
@@ -496,8 +494,6 @@ UpdateIndexRelation(Oid indexoid,
496494
* close the relation and free the tuple
497495
*/
498496
heap_close(pg_index, RowExclusiveLock);
499-
pfree(predText);
500-
pfree(indexForm);
501497
heap_freetuple(tuple);
502498
}
503499

0 commit comments

Comments
 (0)