#include "postgres.h"#include "access/hash.h"#include "access/reloptions.h"#include "access/relscan.h"#include "utils/lsyscache.h"#include "utils/rel.h"
Go to the source code of this file.
Functions | |
| bool | _hash_checkqual (IndexScanDesc scan, IndexTuple itup) |
| uint32 | _hash_datum2hashkey (Relation rel, Datum key) |
| uint32 | _hash_datum2hashkey_type (Relation rel, Datum key, Oid keytype) |
| Bucket | _hash_hashkey2bucket (uint32 hashkey, uint32 maxbucket, uint32 highmask, uint32 lowmask) |
| uint32 | _hash_log2 (uint32 num) |
| void | _hash_checkpage (Relation rel, Buffer buf, int flags) |
| Datum | hashoptions (PG_FUNCTION_ARGS) |
| uint32 | _hash_get_indextuple_hashkey (IndexTuple itup) |
| IndexTuple | _hash_form_tuple (Relation index, Datum *values, bool *isnull) |
| OffsetNumber | _hash_binsearch (Page page, uint32 hash_value) |
| OffsetNumber | _hash_binsearch_last (Page page, uint32 hash_value) |
| OffsetNumber _hash_binsearch | ( | Page | page, | |
| uint32 | hash_value | |||
| ) |
Definition at line 287 of file hashutil.c.
References _hash_get_indextuple_hashkey(), Assert, OffsetNumberIsValid, PageGetItem, PageGetItemId, and PageGetMaxOffsetNumber.
Referenced by _hash_pgaddtup(), and _hash_step().
{
OffsetNumber upper;
OffsetNumber lower;
/* Loop invariant: lower <= desired place <= upper */
upper = PageGetMaxOffsetNumber(page) + 1;
lower = FirstOffsetNumber;
while (upper > lower)
{
OffsetNumber off;
IndexTuple itup;
uint32 hashkey;
off = (upper + lower) / 2;
Assert(OffsetNumberIsValid(off));
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
hashkey = _hash_get_indextuple_hashkey(itup);
if (hashkey < hash_value)
lower = off + 1;
else
upper = off;
}
return lower;
}
| OffsetNumber _hash_binsearch_last | ( | Page | page, | |
| uint32 | hash_value | |||
| ) |
Definition at line 325 of file hashutil.c.
References _hash_get_indextuple_hashkey(), Assert, FirstOffsetNumber, OffsetNumberIsValid, PageGetItem, PageGetItemId, and PageGetMaxOffsetNumber.
Referenced by _hash_step().
{
OffsetNumber upper;
OffsetNumber lower;
/* Loop invariant: lower <= desired place <= upper */
upper = PageGetMaxOffsetNumber(page);
lower = FirstOffsetNumber - 1;
while (upper > lower)
{
IndexTuple itup;
OffsetNumber off;
uint32 hashkey;
off = (upper + lower + 1) / 2;
Assert(OffsetNumberIsValid(off));
itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, off));
hashkey = _hash_get_indextuple_hashkey(itup);
if (hashkey > hash_value)
upper = off - 1;
else
lower = off;
}
return lower;
}
Definition at line 156 of file hashutil.c.
References BufferGetBlockNumber(), BufferGetPage, ereport, errcode(), errhint(), errmsg(), ERROR, HASH_MAGIC, HASH_VERSION, HashMetaPageData::hashm_magic, HashMetaPageData::hashm_version, HashPageOpaqueData::hasho_flag, HashPageGetMeta, LH_META_PAGE, MAXALIGN, PageGetSpecialPointer, PageGetSpecialSize, PageIsNew, and RelationGetRelationName.
Referenced by _hash_addovflpage(), _hash_expandtable(), _hash_first(), _hash_freeovflpage(), _hash_getbuf(), _hash_getbuf_with_strategy(), _hash_getovflpage(), _hash_next(), _hash_pgaddtup(), and _hash_step().
{
Page page = BufferGetPage(buf);
/*
* ReadBuffer verifies that every newly-read page passes
* PageHeaderIsValid, which means it either contains a reasonably sane
* page header or is all-zero. We have to defend against the all-zero
* case, however.
*/
if (PageIsNew(page))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains unexpected zero page at block %u",
RelationGetRelationName(rel),
BufferGetBlockNumber(buf)),
errhint("Please REINDEX it.")));
/*
* Additionally check that the special area looks sane.
*/
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
RelationGetRelationName(rel),
BufferGetBlockNumber(buf)),
errhint("Please REINDEX it.")));
if (flags)
{
HashPageOpaque opaque = (HashPageOpaque) PageGetSpecialPointer(page);
if ((opaque->hasho_flag & flags) == 0)
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" contains corrupted page at block %u",
RelationGetRelationName(rel),
BufferGetBlockNumber(buf)),
errhint("Please REINDEX it.")));
}
/*
* When checking the metapage, also verify magic number and version.
*/
if (flags == LH_META_PAGE)
{
HashMetaPage metap = HashPageGetMeta(page);
if (metap->hashm_magic != HASH_MAGIC)
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" is not a hash index",
RelationGetRelationName(rel))));
if (metap->hashm_version != HASH_VERSION)
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("index \"%s\" has wrong hash version",
RelationGetRelationName(rel)),
errhint("Please REINDEX it.")));
}
}
| bool _hash_checkqual | ( | IndexScanDesc | scan, | |
| IndexTuple | itup | |||
| ) |
Definition at line 28 of file hashutil.c.
References DatumGetBool, FunctionCall2Coll(), index_getattr, IndexScanDescData::indexRelation, IndexScanDescData::keyData, IndexScanDescData::numberOfKeys, RelationGetDescr, ScanKeyData::sk_argument, ScanKeyData::sk_attno, ScanKeyData::sk_collation, ScanKeyData::sk_flags, ScanKeyData::sk_func, and SK_ISNULL.
Referenced by _hash_step().
{
/*
* Currently, we can't check any of the scan conditions since we do not
* have the original index entry value to supply to the sk_func. Always
* return true; we expect that hashgettuple already set the recheck flag
* to make the main indexscan code do it.
*/
#ifdef NOT_USED
TupleDesc tupdesc = RelationGetDescr(scan->indexRelation);
ScanKey key = scan->keyData;
int scanKeySize = scan->numberOfKeys;
while (scanKeySize > 0)
{
Datum datum;
bool isNull;
Datum test;
datum = index_getattr(itup,
key->sk_attno,
tupdesc,
&isNull);
/* assume sk_func is strict */
if (isNull)
return false;
if (key->sk_flags & SK_ISNULL)
return false;
test = FunctionCall2Coll(&key->sk_func, key->sk_collation,
datum, key->sk_argument);
if (!DatumGetBool(test))
return false;
key++;
scanKeySize--;
}
#endif
return true;
}
Definition at line 79 of file hashutil.c.
References DatumGetUInt32, FunctionCall1Coll(), HASHPROC, index_getprocinfo(), and RelationData::rd_indcollation.
Referenced by _hash_first(), and _hash_form_tuple().
{
FmgrInfo *procinfo;
Oid collation;
/* XXX assumes index has only one attribute */
procinfo = index_getprocinfo(rel, 1, HASHPROC);
collation = rel->rd_indcollation[0];
return DatumGetUInt32(FunctionCall1Coll(procinfo, collation, key));
}
Definition at line 99 of file hashutil.c.
References DatumGetUInt32, elog, ERROR, get_opfamily_proc(), HASHPROC, OidFunctionCall1Coll(), RelationData::rd_indcollation, RelationData::rd_opfamily, RegProcedureIsValid, and RelationGetRelationName.
Referenced by _hash_first().
{
RegProcedure hash_proc;
Oid collation;
/* XXX assumes index has only one attribute */
hash_proc = get_opfamily_proc(rel->rd_opfamily[0],
keytype,
keytype,
HASHPROC);
if (!RegProcedureIsValid(hash_proc))
elog(ERROR, "missing support function %d(%u,%u) for index \"%s\"",
HASHPROC, keytype, keytype,
RelationGetRelationName(rel));
collation = rel->rd_indcollation[0];
return DatumGetUInt32(OidFunctionCall1Coll(hash_proc, collation, key));
}
| IndexTuple _hash_form_tuple | ( | Relation | index, | |
| Datum * | values, | |||
| bool * | isnull | |||
| ) |
Definition at line 254 of file hashutil.c.
References _hash_datum2hashkey(), Assert, index_form_tuple(), tupleDesc::natts, RelationGetDescr, and UInt32GetDatum.
Referenced by hashbuildCallback(), and hashinsert().
{
IndexTuple itup;
uint32 hashkey;
Datum hashkeydatum;
TupleDesc hashdesc;
if (isnull[0])
hashkeydatum = (Datum) 0;
else
{
hashkey = _hash_datum2hashkey(index, values[0]);
hashkeydatum = UInt32GetDatum(hashkey);
}
hashdesc = RelationGetDescr(index);
Assert(hashdesc->natts == 1);
itup = index_form_tuple(hashdesc, &hashkeydatum, isnull);
return itup;
}
| uint32 _hash_get_indextuple_hashkey | ( | IndexTuple | itup | ) |
Definition at line 238 of file hashutil.c.
References IndexInfoFindDataOffset, and IndexTupleData::t_info.
Referenced by _hash_binsearch(), _hash_binsearch_last(), _hash_doinsert(), _hash_pgaddtup(), _hash_splitbucket(), and _hash_step().
{
char *attp;
/*
* We assume the hash key is the first attribute and can't be null, so
* this can be done crudely but very very cheaply ...
*/
attp = (char *) itup + IndexInfoFindDataOffset(itup->t_info);
return *((uint32 *) attp);
}
Definition at line 122 of file hashutil.c.
Referenced by _hash_doinsert(), _hash_first(), and _hash_splitbucket().
{
Bucket bucket;
bucket = hashkey & highmask;
if (bucket > maxbucket)
bucket = bucket & lowmask;
return bucket;
}
Definition at line 138 of file hashutil.c.
References i.
Referenced by _h_spoolinit(), _hash_expandtable(), and _hash_metapinit().
| Datum hashoptions | ( | PG_FUNCTION_ARGS | ) |
Definition at line 221 of file hashutil.c.
References default_reloptions(), PG_GETARG_BOOL, PG_GETARG_DATUM, PG_RETURN_BYTEA_P, PG_RETURN_NULL, and RELOPT_KIND_HASH.
{
Datum reloptions = PG_GETARG_DATUM(0);
bool validate = PG_GETARG_BOOL(1);
bytea *result;
result = default_reloptions(reloptions, validate, RELOPT_KIND_HASH);
if (result)
PG_RETURN_BYTEA_P(result);
PG_RETURN_NULL();
}
1.7.1