fltrel.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:11k
- /*
- * fltrel.c - Relation Filteration
- * Kernel of GNU SQL-server
- *
- * This file is a part of GNU SQL Server
- *
- * Copyright (c) 1996, 1997, Free Software Foundation, Inc
- * Developed at the Institute of System Programming
- * This file is written by Vera Ponomarenko
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Contacts: gss@ispras.ru
- *
- */
- /* $Id: fltrel.c,v 1.246 1997/04/10 06:57:28 vera Exp $ */
- #include "xmem.h"
- #include "destrn.h"
- #include "strml.h"
- #include "fdcltrn.h"
- extern struct des_nseg desnseg;
- extern char **scptab;
- static u2_t inpn;
- static char *outasp;
- static struct A inpage, inflpage;
- static void
- put_crt (struct A *outpg, char *cort, struct des_tob *dt, struct des_field *df,
- u2_t fdf, u2_t fn, u2_t fln, u2_t * fl)
- {
- char *a, *b;
- u2_t size, scsz, sz;
- u2_t k, kk, fnk;
- char *val, *aval;
- char *arrpnt[BD_PAGESIZE];
- u2_t arrsz[BD_PAGESIZE];
- tuple_break (cort, arrpnt, arrsz, df, fdf, fn);
- aval = val = cort + scscal (cort);
- for (size = 1, k = 0, kk = 0; kk < fln; kk++)
- {
- fnk = fl[kk];
- size += arrsz[fnk];
- k++;
- if (k == 7)
- k = 0;
- }
- if (size == 1)
- return;
- scsz = k / 7;
- if (k % 7 != 0)
- scsz++;
- size += scsz;
- cort = a = getloc (outpg, size, dt);
- b = a + scsz + 1;
- for (k = 0, kk = 0, *a++ = CORT; kk < fln; kk++)
- {
- fnk = fl[kk];
- if ((sz = arrsz[fnk]) != 0)
- {
- bcopy (arrpnt[fnk], b, sz);
- b += sz;
- *a |= BITVL(k); /* a value is present */
- }
- k++;
- if (k == 7)
- {
- k = 0;
- *(++a) = 0;
- }
- }
- if (k == 0)
- a--;
- *a |= EOSC;
- return;
- }
- struct ans_ctob
- rflrel (struct id_rel *pidrel, u2_t fln, u2_t *fl, u2_t slsz, char *sc)
- {
- u2_t fn, fdf, *ali, sn, pn, *afi, *ai, i;
- struct des_field *df, *dftr;
- i2_t n;
- struct des_tob *dt;
- struct des_trel *destrel;
- char *asp = NULL;
- struct ans_ctob ans;
- char *arrpnt[BD_PAGESIZE];
- u2_t arrsz[BD_PAGESIZE];
- struct A outpg;
- sn = pidrel->urn.segnum;
- if (sn == NRSNUM)
- {
- struct des_trel *dtrin;
- char *tuple;
-
- n = pidrel->urn.obnum;
- if ((u2_t) n > desnseg.mtobnum)
- {
- ans.cpncob = NIOB;
- return (ans);
- }
- dtrin = (struct des_trel *) * (desnseg.tobtab + n);
- if (dtrin == NULL)
- {
- ans.cpncob = NIOB;
- return (ans);
- }
- if (((struct prtob *) dtrin)->prob != TREL)
- {
- ans.cpncob = NIOB;
- return (ans);
- }
- fn = dtrin->fieldn;
- fdf = dtrin->fdftr;
- df = (struct des_field *) (dtrin + 1);
- if ((ans.cpncob = testcond (df, fn, fdf, fln, fl, &slsz, sc, 0, NULL)) != OK)
- return (ans);
- dt = gettob (&outpg, dtrsize + fln * rfsize, &n, TREL);
- outasp = outpg.p_shm;
- destrel = (struct des_trel *) dt;
- dftr = (struct des_field *) (destrel + 1);
- pn = dtrin->tobtr.firstpn;
- for (; pn != (u2_t) ~ 0;)
- {
- asp = getwl (&inpage, sn, pn);
- afi = (u2_t *) (asp + phtrsize);
- ali = afi + ((struct p_h_tr *) asp)->linptr;
- for (ai = afi; ai <= ali; ai++)
- if (*ai != 0)
- {
- tuple = asp + *ai;
- if (tstcsel (df, fn, fdf, slsz, sc, tuple, arrpnt, arrsz) != 0)
- put_crt (&outpg, tuple, dt, df, fdf, fn, fln, fl);
- }
- pn = ((struct listtob *) asp)->nextpn;
- putwul (&inpage, 'n');
- }
- if (dtrin->tobtr.prdt.prob == SORT)
- {
- u2_t kn, k1, k2, j, *ks, *ksort;
-
- ksort = (u2_t *) (df + fn);
- ks = (u2_t *) (dftr + fln);
- kn = dtrin->keysntr;
- for (k1 = 0, k2 = 0, i = 0, j = 0; j < fln && k1 < kn; i++)
- if (i == fl[j])
- {
- if (i == ksort[k1])
- ks[k2++] = ksort[k1++];
- j++;
- }
- else if (i == k1)
- k1++;
- if (k2 != 0)
- {
- dt->prdt.prsort = SORT;
- destrel->keysntr = k2;
- }
- }
- }
- else
- {
- struct d_r_t *desrel;
- struct d_sc_i *scind;
- struct ldesscan *disc;
- i4_t rep;
- i2_t num;
- u2_t size;
-
- if ((ans.cpncob = contir (pidrel, &desrel)) != OK)
- return (ans);
- fn = desrel->desrbd.fieldnum;
- fdf = desrel->desrbd.fdfnum;
- df = (struct des_field *) (desrel + 1);
- if ((ans.cpncob = testcond (df, fn, fdf, fln, fl, &slsz, sc, 0, NULL)) != OK)
- return (ans);
- if ((ans.cpncob = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != 0)
- return (ans);
- dt = gettob (&outpg, dtrsize + fln * rfsize, &n, TREL);
- outasp = outpg.p_shm;
- destrel = (struct des_trel *) dt;
- dftr = (struct des_field *) (destrel + 1);
- scind = rel_scan (sn, pidrel->urn.obnum, (char *) desrel, &num,
- 0, NULL, NULL, 0, 0, NULL);
- disc = &scind->dessc;
- rep = fgetnext (disc, &pn, &size, FASTSCAN);
- for (; rep != EOI;)
- {
- while ((asp = getpg (&inpage, sn, pn, 's')) == NULL);
- afi = (u2_t *) (asp + phsize);
- ali = afi + ((struct page_head *) asp)->lastin;
- for (ai = afi; ai <= ali; ai++)
- if (*ai != 0 && CHECK_PG_ENTRY(ai) &&
- fndslc (desrel, asp, ai, sc, slsz, NULL) != 0)
- put_crt (&outpg, asp + *ai, dt, df, fdf, fn, fln, fl);
- putpg (&inpage, 'n');
- rep = getnext (disc, &pn, &size, FASTSCAN);
- }
- destrel->keysntr = 0;
- delscan (num);
- }
- putwul (&outpg, 'm');
- destrel->fieldn = fln;
- destrel->fdftr = 0;
- for (i = 0; i < fln; i++)
- *dftr++ = df[fl[i]];
- ans.idob.segnum = NRSNUM;
- ans.idob.obnum = n;
- return (ans);
- }
- struct ans_ctob
- rflind (struct id_ind *pidind, u2_t fln, u2_t *fl, u2_t slsz, char *sc, u2_t diasz, char *diasc)
- {
- struct d_r_t *desrel;
- u2_t fn, fdf, ind, size, i, j, k1, k2;
- struct des_field *df, *dftr;
- struct des_tid tid;
- u2_t sn, pn, *ai, *kind, *ks, kn, dscsz;
- struct des_tob *dt;
- struct des_trel *destrel;
- struct id_rel *pidrel;
- struct ldesind *di;
- struct d_sc_i *scind;
- struct ldesscan *disc;
- char *asp = NULL, **t;
- i2_t scnum, n;
- struct ans_ctob ans;
- i4_t rep;
- struct A outpg;
- pidrel = &pidind->irii;
- sn = pidrel->urn.segnum;
- if (sn == NRSNUM)
- {
- ans.cpncob = NIOB;
- return (ans);
- }
- if ((ans.cpncob = cont_id (pidind, &desrel, &di)) != OK)
- return (ans);
- fn = desrel->desrbd.fieldnum;
- fdf = desrel->desrbd.fdfnum;
- df = (struct des_field *) (desrel + 1);
- if (testcond (df, fn, fdf, fln, fl, &slsz, sc, 0, NULL) != OK)
- {
- ans.cpncob = NCF;
- return (ans);
- }
- kind = (u2_t *) (di + 1);
- if ((ans.cpncob = testdsc (desrel, &diasz, diasc, kind, &dscsz)) != OK)
- return (ans);
- if ((ans.cpncob = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != 0)
- return (ans);
- kn = di->ldi.kifn & ~UNIQ & MSK21B;
- if ((ans.cpncob = synlsc (RSC, pidrel, diasc, diasz, kn, kind)) != OK)
- return (ans);
- scind = (struct d_sc_i *) lusc (&scnum, scisize, (char *) di, SCI, RSC, fln, fl,
- sc, slsz, 0, NULL, diasz + size2b);
- disc = &scind->dessc;
- disc->curlpn = (u2_t) ~ 0;
- asp = (char *) scind + scisize + slsz + size2b;
- disc->dpnsc = asp;
- t2bpack (diasz, asp);
- disc->dpnsval = asp + size2b + dscsz;
- bcopy (diasc, asp + size2b, diasz);
- di->oscni++;
- size = dtrsize + fln * rfsize;
- dt = gettob (&outpg, size, &n, TREL);
- outasp = outpg.p_shm;
- destrel = (struct des_trel *) dt;
- destrel->fieldn = fln;
- destrel->fdftr = 0;
- dftr = (struct des_field *) (destrel + 1);
- for (i = 0; i < fln; i++)
- *dftr++ = df[fl[i]];
- if ((rep=ind_ftid (disc, &tid,FASTSCAN)) != EOI)
- {
- inpn = tid.tpn;
- while ((asp = getpg (&inpage, sn, inpn, 's')) == NULL);
- }
- for( ; rep != EOI; rep = ind_tid (disc, &tid, FASTSCAN) )
- {
- pn = tid.tpn;
- ind = tid.tindex;
- if (pn != inpn)
- {
- putpg (&inpage, 'n');
- while ((asp = getpg (&inpage, sn, pn, 's')) == NULL);
- }
- ai = (u2_t *) (asp + phsize) + ind;;
- if (*ai != 0 &&
- fndslc (desrel, asp, ai, sc, slsz, NULL) != 0)
- put_crt (&outpg, asp + *ai, dt, df, fdf, fn, fln, fl);
- }
- t = scptab + scnum;
- xfree ((void *) *t);
- *t = NULL;
- ks = (u2_t *) (dftr + fln);
- for (k1 = 0, k2 = 0, i = 0, j = 0; j < fln && k1 < kn; i++)
- if (i == fl[j])
- {
- if (i == kind[k1])
- ks[k2++] = kind[k1++];
- j++;
- }
- else if (i == k1)
- k1++;
- if (k2)
- {
- dt->prdt.prsort = SORT;
- destrel->keysntr = k2;
- }
- putwul (&outpg, 'm');
- delscan (scnum);
- ans.idob.segnum = NRSNUM;
- ans.idob.obnum = n;
- return (ans);
- }
- struct ans_ctob
- rflflt (u2_t idfl, u2_t fln, u2_t * fl, u2_t slsz, char *sc)
- {
- struct d_r_t *desrel;
- struct des_tid *tid, *tidb;
- u2_t fn, fdf;
- struct des_field *df, *dftr;
- struct des_fltr *desfl;
- struct des_trel *destrel;
- u2_t sn, fpn, pn, *afi, *ai, off, oldpn, flpn, k;
- i2_t n;
- struct des_tob *dt;
- char *asp = NULL, *aspfl;
- struct ans_ctob ans;
- struct A outpg;
- if ((u2_t) idfl > desnseg.mtobnum)
- {
- ans.cpncob = NIOB;
- return (ans);
- }
- desfl = (struct des_fltr *) * (desnseg.tobtab + idfl);
- if (desfl == NULL)
- {
- ans.cpncob = NIOB;
- return (ans);
- }
- if (((struct prtob *) desfl)->prob != FLTR)
- {
- ans.cpncob = NIOB;
- return (ans);
- }
- desrel = desfl->pdrtf;
- sn = desrel->segnr;
- fn = desrel->desrbd.fieldnum;
- fdf = desrel->desrbd.fdfnum;
- df = (struct des_field *) (desrel + 1);
- if (testcond (df, fn, fdf, fln, fl, &slsz, sc, 0, NULL) != OK)
- {
- ans.cpncob = NCF;
- return (ans);
- }
- dt = gettob (&outpg, dtrsize + fln * rfsize, &n, TREL);
- outasp = outpg.p_shm;
- destrel = (struct des_trel *) dt;
- destrel->fieldn = fln;
- destrel->fdftr = 0;
- dftr = (struct des_field *) (destrel + 1);
- for (k = 0; k < fln; k++)
- *dftr++ = df[fl[k]];
- fpn = desfl->tobfl.firstpn;
- for (flpn = fpn; flpn != (u2_t) ~ 0;)
- {
- aspfl = getwl (&inflpage, NRSNUM, flpn);
- off = ((struct p_h_f *) aspfl)->freeoff;
- tid = (struct des_tid *) (aspfl + phfsize);
- oldpn = tid->tpn;
- if (sn != NRSNUM)
- while ((asp = getpg (&inpage, sn, oldpn, 's')) == NULL);
- else
- asp = getwl (&inpage, sn, oldpn);
- afi = (u2_t *) (asp + phsize);
- tidb = (struct des_tid *) (aspfl + off);
- for (; tid < tidb; tid++)
- {
- pn = tid->tpn;
- if (oldpn != pn)
- {
- if (sn != NRSNUM)
- {
- putpg (&inpage, 'n');
- while ((asp = getpg (&inpage, sn, pn, 's')) == NULL);
- }
- else
- {
- putwul (&inpage, 'n');
- asp = getwl (&inpage, sn, pn);
- }
- oldpn = pn;
- afi = (u2_t *) (asp + phsize);
- }
- ai = afi + tid->tindex;
- if (*ai != 0)
- put_crt (&outpg, asp + *ai, dt, df, fdf, fn, fln, fl);
- }
- flpn = ((struct listtob *) aspfl)->nextpn;
- putwul (&inflpage, 'n');
- }
- putwul (&outpg, 'm');
- if (desfl->tobfl.prdt.prsort == SORT && destrel->keysntr == 0)
- dt->prdt.prsort = SORT;
- ans.cpncob = OK;
- ans.idob.segnum = NRSNUM;
- ans.idob.obnum = n;
- return (ans);
- }