next.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:12k
- /*
- * next.c - Find a row
- * 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: next.c,v 1.246 1997/04/28 12:15:01 vera Exp $ */
- #include <assert.h>
- #include "destrn.h"
- #include "strml.h"
- #include "fdcltrn.h"
- #include "xmem.h"
- extern char **scptab;
- extern i2_t maxscan;
- static struct des_field *df;
- static u2_t fn_tab, fdf, slsz;
- static char *arrpnt[BD_PAGESIZE];
- static u2_t arrsz[BD_PAGESIZE];
- static char *selc;
- #define PUT_VALUE(fn, adf)
- {
- if ((pnt = arrpnt[fn]) != NULL) /* a value is present */
- {
- *sc++ = 1;
- if ((type = adf->field_type) != TCH && type != TFL)
- {
- size += size2b;
- t2bpack (adf->field_size, values);
- values += size2b;
- }
- sz = arrsz[fn];
- size += sz;
- bcopy (pnt, values, sz);
- values += sz;
- }
- else
- *sc++ = 0;
- }
- static int
- ansfrm (char *sc)
- {
- char *pnt, *values;
- u2_t sz, size, type, fn;
- struct des_field * adf;
- values = sc + fn_tab;
- size = fn_tab;
- for (fn = 0; fn < fn_tab; fn++)
- {
- adf = df + fn;
- PUT_VALUE(fn, adf);
- }
- return (size);
- }
- static int
- selfld (char *sc, u2_t fln, u2_t *fl)
- {
- char *pnt, *values;
- u2_t fnk, fn, type;
- u2_t size, sz;
- struct des_field * adf;
-
- values = sc + fln;
- size = fln;
- for (fn = 0; fn < fln; fn++)
- {
- fnk = fl[fn];
- adf = df + fnk;
- PUT_VALUE(fnk, adf);
- }
- return (size);
- }
- static void
- ans_frm (struct ans_next *ans, u2_t fln, u2_t *fl)
- {
- char *sc;
- i4_t size;
-
- sc = ans->cadnxt;
- if (fln == 0)
- size = ansfrm (sc);
- else
- size = selfld (sc, fln, fl);
- ans->csznxt = size;
- ans->cotnxt = OK;
- }
- static int
- fndcort (struct A *pg, char *tuple)
- {
- i4_t ans = OK;
- unsigned char t;
- struct A inpage;
- t = *tuple & MSKCORT;
- if (t == CREM || t == IDTR)
- return (NCR);
- if (t == IND)
- {
- u2_t pn2, ind2, *ai2;
- char *asp2;
-
- ind2 = t2bunpack (tuple + 1);
- pn2 = t2bunpack (tuple + 1 + size2b);
- while ((asp2 = getpg (&inpage, pg->p_sn, pn2, 's')) == NULL);
- ai2 = (u2_t *) (asp2 + phsize) + ind2;
- assert (*ai2 != 0);
- tuple = asp2 + *ai2;
- }
- if (slsz != 0)
- ans = tstcsel (df, fn_tab, fdf, slsz, selc, tuple, arrpnt, arrsz);
- else
- tuple_break (tuple, arrpnt, arrsz, df, fdf, fn_tab);
- if (ans == OK)
- {
- if (t == IND)
- {
- putpg (pg, 'n');
- *pg = inpage;
- }
- return (OK);
- }
- else
- {
- if (t == IND)
- putpg (&inpage, 'n');
- return (NCR);
- }
- }
- void
- next (struct ans_next *ans, i4_t scnum)
- {
- struct d_mesc *scpr;
- i4_t sctype;
- struct d_r_t *desrel;
- u2_t pn, ind, *ai, *afi, *ali, sn, cpn;
- struct des_tid tid;
- char *asp = NULL;
- u2_t *fl, fln, fmn;
- struct A pg;
- if ( scnum > maxscan)
- {
- ans->cotnxt = NDSC;
- return;
- }
- scpr = (struct d_mesc *) * (scptab + scnum);
- if (scpr == NULL)
- {
- ans->cotnxt = NDSC;
- return;
- }
- fln = scpr->fnsc;
- if ((sctype = scpr->obsc) == SCR)
- { /* relation scan */
- struct d_sc_i *scind;
- struct ldesscan *desscan;
- u2_t size;
-
- scind = (struct d_sc_i *) scpr;
- desscan = &scind->dessc;
- desrel = (struct d_r_t *) scpr->pobsc;
- sn = desrel->segnr;
- df = (struct des_field *) (desrel + 1);
- fdf = desrel->desrbd.fdfnum;
- fn_tab = desrel->desrbd.fieldnum;
- fl = (u2_t *) (scind + 1);
- fmn = scpr->fmnsc;
- slsz = t2bunpack ((char *) (fl + fln + fmn));
- selc = (char *) (fl + fln + fmn + 1);
- pn = desscan->ctidi.tpn;
- if (pn == (u2_t) ~ 0)
- {
- ans->cotnxt = EOSCAN;
- return;
- }
- ind = desscan->ctidi.tindex;
- if (scpr->prcrt != 0)
- ind += 1;
- do
- {
- while ((asp = getpg (&pg, sn, pn, 's')) == NULL);
- afi = (u2_t *) (asp + phsize);
- ali = afi + ((struct page_head *) asp)->lastin;
- for (ai = afi + ind; ai <= ali; ai++, ind++)
- if (*ai != 0 && CHECK_PG_ENTRY(ai) &&
- fndcort (&pg, asp + *ai) == OK)
- {
- ans_frm (ans, fln, fl);
- putpg (&pg, 'n');
- desscan->ctidi.tpn = pn;
- desscan->ctidi.tindex = ind;
- scpr->prcrt = 1;
- return;
- }
- putpg (&pg, 'n');
- ind = 0;
- }
- while (getnext (desscan, &pn, &size, SLOWSCAN) != EOI);
- desscan->ctidi.tpn = (u2_t) ~ 0;
- }
- else if (sctype == SCTR)
- {
- struct d_sc_r *screl;
- struct des_trel *destrel;
-
- screl = (struct d_sc_r *) scpr;
- destrel = (struct des_trel *) scpr->pobsc;
- df = (struct des_field *) (destrel + 1);
- fdf = destrel->fdftr;
- fn_tab = destrel->fieldn;
- fl = (u2_t *) (screl + 1);
- fmn = scpr->fmnsc;
- slsz = t2bunpack ((char *) (fl + fln + fmn));
- selc = (char *) (fl + fln + fmn + 1);
- pn = screl->curtid.tpn;
- if (pn == (u2_t) ~ 0)
- {
- ans->cotnxt = EOSCAN;
- return;
- }
- ind = screl->curtid.tindex;
- if (scpr->prcrt != 0)
- ind += 1;
- for (; pn != (u2_t) ~ 0; ind = 0)
- {
- asp = getwl (&pg, NRSNUM, pn);
- afi = (u2_t *) (asp + phtrsize);
- ali = afi + ((struct p_h_tr *) asp)->linptr;
- for (ai = afi + ind; ai <= ali; ai++, ind++)
- if (*ai != 0 && tstcsel (df, fn_tab, fdf, slsz, selc, asp + *ai, arrpnt, arrsz) != 0)
- {
- ans_frm (ans, fln, fl);
- putwul (&pg, 'n');
- screl->curtid.tpn = pn;
- screl->curtid.tindex = ind;
- scpr->prcrt = 1;
- return;
- }
- pn = ((struct listtob *) asp)->nextpn;
- putwul (&pg, 'n');
- }
- screl->curtid.tpn = (u2_t) ~ 0;
- }
- else if (sctype == SCI)
- { /* index scan */
- struct d_sc_i *scind;
- struct ldesscan *desscan;
-
- scind = (struct d_sc_i *) scpr;
- desscan = &scind->dessc;
- desrel = desscan->pdi->dri;
- sn = desrel->segnr;
- fl = (u2_t *) (scind + 1);
- fmn = scpr->fmnsc;
- slsz = t2bunpack ((char *) (fl + fln + fmn));
- selc = (char *) (fl + fln + fmn + 1);
- df = (struct des_field *) (desrel + 1);
- fdf = desrel->desrbd.fdfnum;
- fn_tab = desrel->desrbd.fieldnum;
- tid = desscan->ctidi;
- if (tid.tpn == (u2_t) ~ 0)
- {
- ans->cotnxt = EOSCAN;
- return;
- }
- if ((scpr->prcrt == 0) || ind_tid (desscan, &tid, SLOWSCAN) == OK)
- {
- cpn = tid.tpn;
- while ((asp = getpg (&pg, sn, cpn, 's')) == NULL);
- ai = (u2_t *) (asp + phsize) + tid.tindex;
- if (*ai != 0 && fndcort (&pg, asp + *ai) == OK)
- {
- ans_frm (ans, fln, fl);
- putpg (&pg, 'n');
- desscan->ctidi = tid;
- scpr->prcrt = 1;
- return;
- }
- for (; ind_tid (desscan, &tid, SLOWSCAN) != EOI;)
- {
- if ((pn = tid.tpn) != cpn)
- {
- putpg (&pg, 'n');
- while ((asp = getpg (&pg, sn, pn, 's')) == NULL);
- cpn = pn;
- }
- ai = (u2_t *) (asp + phsize) + tid.tindex;
- if (*ai != 0 && fndcort (&pg, asp + *ai) == OK)
- {
- ans_frm (ans, fln, fl);
- putpg (&pg, 'n');
- desscan->ctidi = tid;
- scpr->prcrt = 1;
- return;
- }
- }
- putpg (&pg, 'n');
- } /* if */
- desscan->ctidi.tpn = (u2_t) ~ 0;
- }
- else
- { /* filter scan */
- struct d_sc_f *scfltr;
- char *aspf;
- u2_t nxtpn, off, fpn;
- struct A fpage;
-
- scfltr = (struct d_sc_f *) scpr;
- desrel = ((struct des_fltr *) scpr->pobsc)->pdrtf;
- sn = desrel->segnr;
- fl = (u2_t *) (scfltr + 1);
- fmn = scpr->fmnsc;
- slsz = t2bunpack ((char *) (fl + fln + fmn));
- selc = (char *) (fl + fln + fmn + 1);
- df = (struct des_field *) (desrel + 1);
- fdf = desrel->desrbd.fdfnum;
- fn_tab = desrel->desrbd.fieldnum;
- pn = (u2_t) ~ 0;
- for (fpn = scfltr->pnf, nxtpn = fpn; fpn != (u2_t) ~ 0; fpn = nxtpn)
- {
- aspf = getwl (&fpage, NRSNUM, fpn);
- for (off = scfltr->offf; off < BD_PAGESIZE; off += size2b)
- {
- tid = *(struct des_tid *) (aspf + scfltr->offf);
- nxtpn = ((struct listtob *) aspf)->nextpn;
- if ((cpn = tid.tpn) != pn)
- {
- if (pn != (u2_t) ~ 0)
- putpg (&pg, 'n');
- while ((asp = getpg (&pg, sn, cpn, 's')) == NULL);
- }
- ai = (u2_t *) (asp + phsize) + tid.tindex;
- if (*ai != 0 && fndcort (&pg, asp + *ai) == OK)
- {
- ans_frm (ans, fln, fl);
- putpg (&pg, 'n');
- scfltr->pnf = pn;
- scfltr->offf = off;
- scpr->prcrt = 1;
- return;
- }
- }
- putwul (&fpage, 'n');
- }
- scfltr->pnf = (u2_t) ~ 0;
- }
- scpr->prcrt = 0;
- ans->cotnxt = EOSCAN;
- return;
- }
- void
- readrow (struct ans_next *ans, i4_t scnum, i4_t fln, u2_t * fl)
- {
- struct d_mesc *scpr;
- struct d_r_t *desrel;
- u2_t *ai;
- i4_t sctype;
- struct des_tid tid;
- char *asp = NULL;
- struct A pg;
- scpr = (struct d_mesc *) * (scptab + scnum);
- if (scnum >= maxscan || scpr == NULL)
- {
- ans->cotnxt = NCF;
- return;
- }
- if (scpr->prcrt == 0)
- {
- ans->cotnxt = NCR;
- return;
- }
- if ((sctype = scpr->obsc) == SCTR)
- {
- struct d_sc_r *screl;
- struct des_trel *destrel;
-
- screl = (struct d_sc_r *) scpr;
- destrel = (struct des_trel *) scpr->pobsc;
- df = (struct des_field *) (destrel + 1);
- fdf = destrel->fdftr;
- fn_tab = destrel->fieldn;
- tid = screl->curtid;
- asp = getwl (&pg, NRSNUM, tid.tpn);
- ai = (u2_t *) (asp + phtrsize) + tid.tindex;
- tuple_break (asp + *ai, arrpnt, arrsz, df, fdf, fn_tab);
- ans_frm (ans, fln, fl);
- putwul (&pg, 'n');
- return;
- }
- else if (sctype == SCR)
- { /* relation scan */
- struct d_sc_i *scind;
- struct ldesscan *desscan;
-
- scind = (struct d_sc_i *) scpr;
- desscan = &scind->dessc;
- desrel = (struct d_r_t *) scpr->pobsc;
- tid = desscan->ctidi;
- }
- else if (sctype == SCI)
- { /* index scan */
- struct d_sc_i *scind;
- struct ldesscan *desscan;
-
- scind = (struct d_sc_i *) scpr;
- desscan = &scind->dessc;
- desrel = desscan->pdi->dri;
- tid = desscan->ctidi;
- }
- else
- { /* filter scan */
- struct d_sc_f *scfltr;
-
- scfltr = (struct d_sc_f *) scpr;
- desrel = ((struct des_fltr *) scpr->pobsc)->pdrtf;
- asp = getwl (&pg, NRSNUM, scfltr->pnf);
- tid = *(struct des_tid *) (asp + scfltr->offf);
- putwul (&pg, 'n');
- }
- df = (struct des_field *) (desrel + 1);
- fdf = desrel->desrbd.fdfnum;
- fn_tab = desrel->desrbd.fieldnum;
- while ((asp = getpg (&pg, desrel->segnr, tid.tpn, 's')) == NULL);
- ai = (u2_t *) (asp + phsize) + tid.tindex;
- slsz = 0;
- selc = NULL;
- if (fndcort (&pg, asp + *ai) != OK)
- {
- ans->cotnxt = NCR;
- return;
- }
- ans_frm (ans, fln, fl);
- putpg (&pg, 'n');
- return;
- }