ING_DB
This commit is contained in:
parent
71b63a8731
commit
30af3311d4
|
|
@ -0,0 +1,361 @@
|
|||
# include <stdio.h>
|
||||
# include "gen.h"
|
||||
# include "../h/dbs.h"
|
||||
# include "../h/aux.h"
|
||||
# include "../h/symbol.h"
|
||||
# include "../h/tree.h"
|
||||
# include "../h/pipes.h"
|
||||
# include "ovqp.h"
|
||||
# include "strategy.h"
|
||||
|
||||
|
||||
/*
|
||||
** Exactkey checks to see if the relation described
|
||||
** by "ap" can be used in a hashed scan.
|
||||
** All the key domains of the relation must
|
||||
** have simple clauses of equality associated
|
||||
** with them in the qualification.
|
||||
**
|
||||
** Returns 0 if the relation can't be used.
|
||||
**
|
||||
** Returns > 0 if it can.
|
||||
*/
|
||||
|
||||
exactkey(ap, key)
|
||||
struct accessparam *ap;
|
||||
struct key *key;
|
||||
{
|
||||
register struct accessparam *a;
|
||||
register struct key *k;
|
||||
register struct simp *s;
|
||||
int d;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
# ifdef xOTR1
|
||||
AAtTfp(25, -1, "EXACTKEY\n");
|
||||
# endif
|
||||
|
||||
a = ap;
|
||||
k = key;
|
||||
i = 0;
|
||||
if (a->mode == EXACTKEY)
|
||||
{
|
||||
|
||||
for (i = 0; d = a->keydno[i]; i++)
|
||||
{
|
||||
|
||||
s = Simp;
|
||||
for (j = 0; j < Nsimp; j++)
|
||||
{
|
||||
if (s->relop == (int) opEQ && s->att == d)
|
||||
{
|
||||
k->keysym = s->konst;
|
||||
k->dnumber = (a->sec_index == TRUE) ? i+1 : d;
|
||||
k++;
|
||||
# ifdef xOTR1
|
||||
if (AAtTfp(25, 1, "exact key on dom %d\tvalue=", d))
|
||||
prsym(s->konst);
|
||||
# endif
|
||||
break;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (j == Nsimp)
|
||||
{
|
||||
i = 0; /* failure. at lease one key isn't used */
|
||||
break;
|
||||
}
|
||||
}
|
||||
k->dnumber = 0; /* mark end of list */
|
||||
}
|
||||
# ifdef xOTR1
|
||||
AAtTfp(25, 9, "EXACTKEY: rets %d\n", i);
|
||||
# endif
|
||||
return (i);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Range key checks if the relation described by
|
||||
** "ap" is ISAM and there are simple clauses
|
||||
** on the first key and any additional keys.
|
||||
**
|
||||
** Rangekey accumulates both high and low keys,
|
||||
** which are not necessary the same. If it
|
||||
** every finds a high or a low key on the first
|
||||
** domain of the relation then success=TRUE.
|
||||
**
|
||||
** Returns 1 if Rangekey ok
|
||||
** 0 if Rangekey is not ok
|
||||
** -1 if Rangekey ok and all clauses are equality clauses
|
||||
*/
|
||||
|
||||
rangekey(ap, l, h)
|
||||
struct accessparam *ap;
|
||||
struct key *l;
|
||||
struct key *h;
|
||||
{
|
||||
register struct key *low;
|
||||
register struct key *high;
|
||||
register struct simp *s;
|
||||
struct accessparam *a;
|
||||
int sec_indx;
|
||||
int d;
|
||||
int i;
|
||||
int rel;
|
||||
int success;
|
||||
int ns;
|
||||
int lowkey;
|
||||
int allexact;
|
||||
|
||||
# ifdef xOTR1
|
||||
AAtTfp(25, 5, "RANGEKEY\n");
|
||||
# endif
|
||||
|
||||
a = ap;
|
||||
sec_indx = a->sec_index == TRUE;
|
||||
low = l;
|
||||
high = h;
|
||||
allexact = -1; /* assume all clauses equality clauses */
|
||||
s = Simp;
|
||||
success = FALSE;
|
||||
if (a->mode == LRANGEKEY)
|
||||
{
|
||||
|
||||
for (ns = 0; ns < Nsimp; ns++)
|
||||
{
|
||||
rel = s->relop;
|
||||
for (i = 0; d = a->keydno[i]; i++)
|
||||
{
|
||||
if (d == s->att)
|
||||
{
|
||||
/* this is either a high range value or low range value */
|
||||
lowkey = (rel == (int) opGTGE);
|
||||
if (lowkey || rel == (int) opEQ)
|
||||
{
|
||||
/* low range key */
|
||||
# ifdef xOTR1
|
||||
AAtTfp(25, 6, "low key on dom %d\t", d);
|
||||
# endif
|
||||
low->keysym = s->konst;
|
||||
low->dnumber = sec_indx ? i+1 : d;
|
||||
low++;
|
||||
}
|
||||
if (!lowkey || rel == (int) opEQ)
|
||||
{
|
||||
/* high range key */
|
||||
# ifdef xOTR1
|
||||
AAtTfp(25, 6, "high key on dom %d\t", d);
|
||||
# endif
|
||||
high->keysym = s->konst;
|
||||
high->dnumber = sec_indx ? i+1 : d;
|
||||
high++;
|
||||
}
|
||||
# ifdef xOTR1
|
||||
if (AAtTf(25, 6))
|
||||
prsym(s->konst);
|
||||
# endif
|
||||
if (i == 0)
|
||||
success = TRUE;
|
||||
if (rel != (int) opEQ)
|
||||
allexact = 1; /* at least one inequality */
|
||||
break;
|
||||
}
|
||||
}
|
||||
s++; /* try next simple clause */
|
||||
}
|
||||
}
|
||||
|
||||
high->dnumber = 0; /* mark end of list */
|
||||
low->dnumber = 0; /* mask end of list */
|
||||
|
||||
/* if success then return whether all clauses were equality */
|
||||
if (success)
|
||||
success = allexact;
|
||||
|
||||
# ifdef xOTR1
|
||||
AAtTfp(25, 5, "RANGEKEY: rets %d\n", success);
|
||||
# endif
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
setallkey(relkey, keytuple)
|
||||
struct key *relkey;
|
||||
char *keytuple;
|
||||
|
||||
/*
|
||||
** Setallkey takes a key struct, decodes it and
|
||||
** calls setkey with each value.
|
||||
**
|
||||
** Called from strategy().
|
||||
**
|
||||
** returns 0 if ok.
|
||||
** returns -1 in the special case of a deblanked hashkey
|
||||
** being bigger than the corresponding domain.
|
||||
*/
|
||||
{
|
||||
register struct key *k;
|
||||
register SYMBOL *sy;
|
||||
register int dnum;
|
||||
SYMBOL **s;
|
||||
char *p;
|
||||
char temp[MAXFIELD + 1];
|
||||
int l;
|
||||
|
||||
AAam_clearkeys(Scanr);
|
||||
k = relkey;
|
||||
while (dnum = k->dnumber)
|
||||
{
|
||||
s = &k->keysym;
|
||||
sy = (SYMBOL *) Stack;
|
||||
getsymbol(sy, &s); /* copy symbol to stack. caution:getsym changes the value of s. */
|
||||
rcvt(sy, Scanr->relfrmt[dnum], Scanr->relfrml[dnum]); /* convert key to correct type */
|
||||
p = (char *) (sy->value);
|
||||
|
||||
if (sy->type == CHAR)
|
||||
{
|
||||
/*
|
||||
** The length of a character key must
|
||||
** be made equal to the domain length.
|
||||
** The key is copied to a temp place
|
||||
** and a null byte is inserted at the
|
||||
** end. In addition, if the key without
|
||||
** blanks is longer than the domain and
|
||||
** this is an exactkey, then the query
|
||||
** is false.
|
||||
*/
|
||||
p = temp;
|
||||
l = cmove(sy, p); /* copy symbol to temp removing blanks & nulls */
|
||||
# ifdef xOTR1
|
||||
AAtTfp(26, 9, "length is %d\n", l);
|
||||
# endif
|
||||
if (Fmode == EXACTKEY && l > ctou(Scanr->relfrml[dnum]))
|
||||
/* key too large. qualification is false */
|
||||
return (-1);
|
||||
}
|
||||
if (sy->type == INT && sy->len == sizeof (char))
|
||||
{
|
||||
*temp = ((I2TYPE *) p)->i2type;
|
||||
p = temp;
|
||||
}
|
||||
AAam_setkey(Scanr, keytuple, p, dnum); /* set the key */
|
||||
k++;
|
||||
}
|
||||
# ifdef xOTR1
|
||||
if (AAtTf(26, 8))
|
||||
AAprkey(Scanr, keytuple);
|
||||
# endif
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
cmove(sym, dest)
|
||||
struct stacksym *sym;
|
||||
char *dest;
|
||||
|
||||
/*
|
||||
** Cmove copies a char symbol into "dest".
|
||||
** It stops when the length is reached or
|
||||
** when a null byte is found.
|
||||
**
|
||||
** returns the number of non-blank chars
|
||||
** in the string.
|
||||
*/
|
||||
{
|
||||
register char *d;
|
||||
register char *s;
|
||||
register int l;
|
||||
int blank;
|
||||
|
||||
s = (char *) ((SYMBOL *) sym)->value;
|
||||
s = ((STRINGP *) s)->stringp; /* s points to the char string */
|
||||
d = dest;
|
||||
blank = 0;
|
||||
|
||||
for (l = (ctou(((SYMBOL *) sym)->len)); l--; s++)
|
||||
{
|
||||
*d++ = *s;
|
||||
if (*s == ' ')
|
||||
blank++;
|
||||
if (*s == '\0')
|
||||
{
|
||||
d--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*d = '\0';
|
||||
return ((d - dest) - blank); /* return length of string */
|
||||
}
|
||||
|
||||
indexcheck()
|
||||
|
||||
/*
|
||||
** Indexcheck is called by scan() to check whether
|
||||
** a secondary index tuple satisfies the simple
|
||||
** clauses under which it was scanned.
|
||||
**
|
||||
** Returns 1 if the tuple is ok,
|
||||
** 0 otherwise.
|
||||
*/
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (Fmode == EXACTKEY)
|
||||
i = keycheck(Lkey_struct, Keyl, 0); /* check for equality */
|
||||
else
|
||||
{
|
||||
i = keycheck(Lkey_struct, Keyl, 1); /* check for >= */
|
||||
/* If the lowkey passed, check the highkey also */
|
||||
if (i)
|
||||
i = keycheck(Hkey_struct, Keyh, -1); /* check for <= */
|
||||
}
|
||||
# ifdef xOTR1
|
||||
AAtTfp(26, 10, "INDEXCHECK: rets %d\n", i);
|
||||
# endif
|
||||
return (i);
|
||||
}
|
||||
|
||||
keycheck(keys, keytuple, mode)
|
||||
struct key *keys;
|
||||
char *keytuple;
|
||||
int mode;
|
||||
|
||||
/*
|
||||
** Keycheck compares Intup with keytuple
|
||||
** according to the domains specified in the
|
||||
** "keys" struct.
|
||||
**
|
||||
** mode is either >0, =0, <0 depending on
|
||||
** whether check is for Intup >= keytuple,
|
||||
** Intup == keytuple, Intup <= keytuple respectively
|
||||
**
|
||||
** returns TRUE or FALSE accordingly.
|
||||
*/
|
||||
{
|
||||
register struct key *k;
|
||||
register char *kp;
|
||||
register int dnum;
|
||||
register int offset;
|
||||
register int i;
|
||||
register int success;
|
||||
|
||||
kp = keytuple;
|
||||
success = TRUE;
|
||||
|
||||
for (k = keys; dnum = k->dnumber; k++)
|
||||
{
|
||||
|
||||
offset = Scanr->reloff[dnum];
|
||||
if (i = AAicompare(&Intup[offset], &kp[offset], Scanr->relfrmt[dnum], ctou(Scanr->relfrml[dnum])))
|
||||
{
|
||||
if (i < 0 && mode < 0 || i > 0 && mode > 0)
|
||||
continue;
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (success);
|
||||
}
|
||||
Loading…
Reference in New Issue