From 30af3311d44dbb772da036abddc4d09e9e20b646 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Mon, 11 Dec 1989 11:13:03 +0000 Subject: [PATCH] ING_DB --- WEGA/contrib/ingres/dbs/src/ovqp/key.c | 361 +++++++++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 WEGA/contrib/ingres/dbs/src/ovqp/key.c diff --git a/WEGA/contrib/ingres/dbs/src/ovqp/key.c b/WEGA/contrib/ingres/dbs/src/ovqp/key.c new file mode 100644 index 0000000..87ca9da --- /dev/null +++ b/WEGA/contrib/ingres/dbs/src/ovqp/key.c @@ -0,0 +1,361 @@ +# include +# 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); +}