4.3BSD/usr/ingres/source/iutil/find.c
# include <ingres.h>
# include <aux.h>
# include <symbol.h>
# include <access.h>
# include <lock.h>
# include <btree.h>
# include <sccs.h>
SCCSID(@(#)find.c 8.1 12/31/84)
/*
** Find - determine limits for scan of a relation
**
** Find determines the values of an initial TID
** and an ending TID for scanning a relation.
** The possible calls to find are:
**
** find(desc, NOKEY, lotid, hightid)
** sets tids to scan entire relation
**
** find(desc, EXACTKEY, lotid, hightid, key)
** sets tids according to structure
** of the relation. Key should have
** been build using setkey.
**
** find(desc, LRANGEKEY, lotid, hightid, keylow)
** Finds lotid less then or equal to keylow
** for isam relations. Otherwise scans whole relation.
** This call should be followed by a call with HRANGEKEY.
**
** find(desc, HRANGEKEY, lotid, hightid, keyhigh)
** Finds hightid greater than or equal to
** keyhigh for isam relations. Otherwise sets
** hightid to maximum scan.
**
** find(desc, FULLKEY, lotid, hightid, key)
** Same as find with EXACTKEY and all keys
** provided. This mode is used only by findbest
** and replace.
**
** returns:
** <0 fatal error
** 0 success
**
** Trace Flags:
** 22.0-8
*/
find(d, mode, lotid, hightid, key)
register DESC *d;
int mode;
TID *lotid;
TID *hightid;
char *key;
{
register int ret;
bool keyok;
long pageid, lid[MAXLID], page;
long rhash(), get_tid();
struct locator tid_id;
char *tp;
int i;
extern int Btree_fd;
# ifdef xATR1
if (tTf(22, 0))
{
printf("find: m%d,s%d,%.14s\n", mode, d->reldum.relspec, d->reldum.relid);
if (mode != NOKEY)
printup(d, key);
}
# endif
ret = 0; /* assume successful return */
keyok = FALSE;
switch (mode)
{
case EXACTKEY:
keyok = fullkey(d);
break;
case FULLKEY:
keyok = TRUE;
case NOKEY:
case LRANGEKEY:
case HRANGEKEY:
case BTREEKEY:
break;
default:
syserr("FIND: bad mode %d", mode);
}
/* set lotid for beginning of scan */
if (mode != HRANGEKEY)
{
pageid = 0;
stuff_page(lotid, &pageid);
lotid->line_id = -1;
}
/* set hitid for end of scan */
if (mode != LRANGEKEY)
{
pageid = -1;
stuff_page(hightid, &pageid);
hightid->line_id = -1;
}
if (mode == BTREEKEY)
/* set tid to value as found using B-Tree */
{
tp = key + d->reldum.relwid - LIDSIZE * d->reldum.reldim;
bmove(tp, lid, LIDSIZE * d->reldum.reldim);
Btree_fd = d->btree_fd;
page = RT;
for (i = 0; i < d->reldum.reldim; ++i)
{
pageid = get_tid(page, lid[i], &tid_id);
if (pageid < 0)
break;
page = pageid;
}
if (pageid >= 0)
bmove(&pageid, lotid, LIDSIZE);
}
else if (mode != NOKEY)
{
switch (abs(d->reldum.relspec))
{
case M_HEAP:
break;
case M_ISAM:
if (mode != HRANGEKEY)
{
/* compute lo limit */
if (ret = ndxsearch(d, lotid, key, -1, keyok))
break; /* fatal error */
}
/* if the full key was provided and mode is exact, then done */
if (keyok)
{
bmove((char *) lotid, (char *) hightid, sizeof *lotid);
break;
}
if (mode != LRANGEKEY)
ret = ndxsearch(d, hightid, key, 1, keyok);
break;
case M_HASH:
if (!keyok)
break; /* can't do anything */
pageid = rhash(d, key);
stuff_page(lotid, &pageid);
stuff_page(hightid, &pageid);
break;
default:
ret = acc_err(AMFIND_ERR);
}
}
# ifdef xATR2
if (tTf(22, 1))
{
printf("find: ret %d\tlow", ret);
dumptid(lotid);
printf("hi");
dumptid(hightid);
}
# endif
return (ret);
}
/*
** This routine will check that enough of the tuple has been specified
** to enable a key access.
*/
fullkey(des)
DESC *des;
{
register DESC *d;
register int i;
d = des;
for (i = 1; i <= d->reldum.relatts; i++)
if (d->relxtra[i] && !d->relgiven[i])
return (FALSE);
return (TRUE);
}