/* * Per-tuple callback from IndexBuildHeapScan */ static void hashbuildCallback(Relation index, HeapTuple htup, Datum *values, bool *isnull, bool tupleIsAlive, void *state) { HashBuildState *buildstate = (HashBuildState *) state; IndexTuple itup; /* Hash indexes don't index nulls, see notes in hashinsert */ if (isnull[0]) return; /* Either spool the tuple for sorting, or just put it into the index */ if (buildstate->spool) _h_spool(buildstate->spool, &htup->t_self, values, isnull); else { /* form an index tuple and point it at the heap tuple */ itup = _hash_form_tuple(index, values, isnull); itup->t_tid = htup->t_self; _hash_doinsert(index, itup); pfree(itup); } buildstate->indtuples += 1; }
/* * hashinsert() -- insert an index tuple into a hash table. * * Hash on the heap tuple's key, form an index tuple with hash code. * Find the appropriate location for the new tuple, and put it there. */ bool hashinsert(Relation rel, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique) { IndexTuple itup; /* * If the single index key is null, we don't insert it into the index. * Hash tables support scans on '='. Relational algebra says that A = B * returns null if either A or B is null. This means that no * qualification used in an index scan could ever return true on a null * attribute. It also means that indices can't be used by ISNULL or * NOTNULL scans, but that's an artifact of the strategy map architecture * chosen in 1986, not of the way nulls are handled here. */ if (isnull[0]) return false; /* generate an index tuple */ itup = _hash_form_tuple(rel, values, isnull); itup->t_tid = *ht_ctid; _hash_doinsert(rel, itup); pfree(itup); return false; }
/* * hashinsert() -- insert an index tuple into a hash table. * * Hash on the heap tuple's key, form an index tuple with hash code. * Find the appropriate location for the new tuple, and put it there. */ Datum hashinsert(PG_FUNCTION_ARGS) { Relation rel = (Relation) PG_GETARG_POINTER(0); Datum *values = (Datum *) PG_GETARG_POINTER(1); bool *isnull = (bool *) PG_GETARG_POINTER(2); ItemPointer ht_ctid = (ItemPointer) PG_GETARG_POINTER(3); #ifdef NOT_USED Relation heapRel = (Relation) PG_GETARG_POINTER(4); IndexUniqueCheck checkUnique = (IndexUniqueCheck) PG_GETARG_INT32(5); #endif IndexTuple itup; /* generate an index tuple */ itup = _hash_form_tuple(rel, values, isnull); itup->t_tid = *ht_ctid; /* * If the single index key is null, we don't insert it into the index. * Hash tables support scans on '='. Relational algebra says that A = B * returns null if either A or B is null. This means that no * qualification used in an index scan could ever return true on a null * attribute. It also means that indices can't be used by ISNULL or * NOTNULL scans, but that's an artifact of the strategy map architecture * chosen in 1986, not of the way nulls are handled here. */ if (IndexTupleHasNulls(itup)) { pfree(itup); PG_RETURN_BOOL(false); } _hash_doinsert(rel, itup); pfree(itup); PG_RETURN_BOOL(false); }