2.11BSD/ingres/source/access/find.c
# include "../ingres.h"
# include "../aux.h"
# include "../symbol.h"
# include "../access.h"
# include "../lock.h"
/* tTf flag 92 TTF */
/*
** 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
*/
find(d1, mode, lotid1, hightid, key)
struct descriptor *d1;
int mode;
struct tup_id *lotid1;
struct tup_id *hightid;
char *key;
{
register struct descriptor *d;
register struct tup_id *lotid;
register int ret;
int keyok;
long pageid;
long rhash();
d = d1;
lotid = lotid1;
# ifdef xATR1
if (tTf(92, 0))
{
printf("find: m%d,s%d,%.14s\n", mode, d->relspec, d->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:
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 != NOKEY)
{
switch (abs(d->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(lotid, 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(92, 1))
{
printf("find: ret %d\tlow", ret);
dumptid(lotid);
printf("hi");
dumptid(hightid);
}
# endif
return (ret);
}
fullkey(des)
struct descriptor *des;
/*
* This routine will check that enough of the tuple has been specified
* to enable a key access.
*
*/
{
register struct descriptor *d;
register int i;
d = des;
for (i = 1; i <= d->relatts; i++)
if (d->relxtra[i] && !d->relgiven[i])
return (FALSE);
return (TRUE);
}