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