aggravg.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:9k
- /*
- * aggravg.c - calculation of average aggregate functions
- * 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: aggravg.c,v 1.246 1997/04/10 06:57:28 vera Exp $ */
- #include <assert.h>
- #include "xmem.h"
- #include "destrn.h"
- #include "sctp.h"
- #include "strml.h"
- #include "fdcltrn.h"
- extern struct des_nseg desnseg;
- static int
- agravg (double *avg, i4_t n_avg, u2_t type, char *key, u2_t fn)
- {
- char *sc;
- u2_t k, k1;
- u2_t v22;
- i4_t v42;
- double val;
- sc = key;
- key += scscal (key);
- for (k = 0, k1 = 0; k < fn; k1 = 0, sc++)
- for (; k1 < 7 && k < fn; k++, k1++)
- if ((*sc & BITVL(k1)) != 0)
- key = proval (key, type);
- switch (type)
- {
- case T1B:
- val = *key;
- break;
- case T2B:
- v22 = t2bunpack (key);
- val = v22;
- break;
- case TFLOAT:
- bcopy (key, (char *) &v42, size4b);
- val = v42;
- break;
- case T4B:
- v42 = t4bunpack (key);
- val = v42;
- break;
- default:
- val = 0;
- error ("TRN.agravg: This data type is incorrect");
- break;
- }
- *avg = ((*avg) * n_avg + val) / (n_avg + 1);
- n_avg += 1;
- return (n_avg);
- }
- struct ans_avg
- avgitab (struct id_ind * pidind, u2_t slsz,
- char *sc, u2_t diasz, char *diasc)
- {
- u2_t fn, fdf, sn;
- struct des_field *df;
- struct ldesscan *disc;
- struct d_sc_i *scind;
- struct ldesind *di;
- struct d_r_t *desrel;
- char *asp = NULL;
- struct id_rel *pidrel;
- struct des_tid tid;
- i4_t rep;
- i2_t n;
- u2_t *ai, *afi, kn, type, dscsz;
- i4_t n_avg = 0;
- double avg = 0;
- struct A pg;
- struct ans_avg ans;
- pidrel = &pidind->irii;
- sn = pidrel->urn.segnum;
- if ((ans.cotavg = cont_id (pidind, &desrel, &di)) != OK)
- return (ans);
- fn = desrel->desrbd.fieldnum;
- fdf = desrel->desrbd.fdfnum;
- df = (struct des_field *) (desrel + 1);
- if ((ans.cotavg = testcond (df, fn, fdf, 0, NULL, &slsz, sc, 0, NULL)) != OK)
- return (ans);
- ai = (u2_t *) (di + 1);
- if ((ans.cotavg = testdsc (desrel, &diasz, diasc, ai, &dscsz)) != OK)
- return (ans);
- if ((ans.cotavg = synlsc (RSC, pidrel, sc, slsz, fn, NULL)) != OK)
- return (ans);
- kn = di->ldi.kifn & ~UNIQ & MSK21B;
- if ((ans.cotavg = synlsc (RSC, pidrel, diasc, diasz, kn, ai)) != OK)
- return (ans);
- scind = (struct d_sc_i *) lusc (&n, scisize, (char *) di, SCI, RSC, 0,
- NULL, sc, slsz, 0, NULL, diasz + size2b);
- disc = &scind->dessc;
- disc->pdi = di;
- disc->curlpn = (u2_t) ~ 0;
- asp = (char *) (scind + 1) + slsz + size2b;
- if (diasz == 0)
- disc->dpnsc = NULL;
- else
- disc->dpnsc = asp;
- t2bpack (diasz, asp);
- disc->dpnsval = asp + size2b + dscsz;
- asp += size2b;
- bcopy (diasc, asp, diasz);
- ai = (u2_t *) (disc->pdi + 1);
- type = (df + *ai)->field_type;
- if (type == TCH || type == TFL)
- {
- ans.cotavg = NCF;
- return (ans);
- }
- rep = ind_ftid (disc, &tid, SLOWSCAN);
- n_avg = agravg (&avg, n_avg, type, disc->cur_key, 0);
- for (; rep != EOI; rep = ind_tid (disc, &tid, SLOWSCAN))
- {
- while ((asp = getpg (&pg, sn, tid.tpn, 's')) == NULL);
- afi = (u2_t *) (asp + phsize);
- ai = afi + tid.tindex;
- if (*ai != 0 &&
- fndslc (desrel, asp, ai, sc, slsz, NULL) != 0)
- {
- n_avg = agravg (&avg, n_avg, type, disc->cur_key, 0);
- }
- putpg (&pg, 'n');
- }
- xfree (disc->cur_key);
- delscan (n);
- ans.agr_avg = avg;
- return (ans);
- }
- struct ans_avg
- avgstab (struct id_rel *pidrel)
- {
- u2_t pn, *ai, *afi, *ali, kn, type;
- struct des_field *df;
- struct des_trel *destrel;
- char *asp;
- i2_t ntob;
- i4_t n_avg = 0;
- double avg = 0;
- struct A pg;
- struct ans_avg ans;
- if (pidrel->urn.segnum != NRSNUM)
- ans.cotavg = NIOB;
- ntob = pidrel->urn.obnum;
- if (ntob > desnseg.mtobnum)
- ans.cotavg = NIOB;
- destrel = (struct des_trel *) * (desnseg.tobtab + ntob);
- if (destrel == NULL)
- ans.cotavg = NIOB;
- if (((struct prtob *) destrel)->prob != TREL)
- ans.cotavg = NIOB;
- if (((struct prtob *) destrel)->prsort != SORT)
- ans.cotavg = N_SORT;
- df = (struct des_field *) (destrel + 1);
- kn = *(u2_t *) ((char *) destrel + destrel->fieldn * rfsize);
- type = (df + kn)->field_type;
- if (type == TCH || type == TFL)
- {
- ans.cotavg = NCF;
- return (ans);
- }
- for (pn = destrel->tobtr.firstpn; pn != (u2_t) ~ 0;)
- {
- asp = getwl (&pg, NRSNUM, pn);
- afi = (u2_t *) (asp + phtrsize);
- ali = afi + ((struct p_h_tr *) asp)->linptr;
- for (ai = afi; ai <= ali; ai++)
- if (*ai != 0)
- n_avg = agravg (&avg, n_avg, type, asp + *ai + 1, kn);
- pn = ((struct listtob *) asp)->nextpn;
- putwul (&pg, 'n');
- }
- ans.agr_avg = avg;
- return (ans);
- }
- i4_t
- fndslc (struct d_r_t *desrel, char *asp, u2_t *ai,
- char *selcon, u2_t slsz, char *cort)
- {
- i4_t tuple_size;
- char *tuple;
- unsigned char t;
- u2_t fn, fdf;
- struct des_field * df;
- struct A inpage;
- char *arrpnt[BD_PAGESIZE];
- u2_t arrsz[BD_PAGESIZE];
- tuple = asp + *ai;
- t = *tuple & MSKCORT;
- if (t == CREM || t == IDTR)
- return (0);
- if (t == IND)
- {
- u2_t pn2, ind2;
- ind2 = t2bunpack (tuple + 1);
- pn2 = t2bunpack (tuple + 1 + size2b);
- while ((asp = getpg (&inpage, desrel->segnr, pn2, 's')) == NULL);
- ai = (u2_t *) (asp + phsize) + ind2;
- tuple = asp + *ai;
- }
- fn = desrel->desrbd.fieldnum;
- fdf = desrel->desrbd.fdfnum;
- df = (struct des_field *) (desrel + 1);
- tuple_size = tstcsel (df, fn, fdf, slsz, selcon, tuple, arrpnt, arrsz);
- if (tuple_size != 0 && cort != NULL)
- bcopy (tuple, cort, tuple_size);
- if (t == IND)
- putpg (&inpage, 'n');
- return (tuple_size);
- }
- #define BETWEEN_CMP (t == SS || t == SES || t == SSE || t == SESE)
- static int
- fcv (i4_t t, u2_t field_type, char **sel_vals, char *tuple_value, u2_t tval_length)
- {
- char *b1, *b2;
- i4_t (*f) (char *, char *, u2_t, u2_t);
- u2_t nb1, nb2;
- i4_t v, v1, res;
- if (t == ANY || t == NEQUN)
- return (OK);
- switch (field_type)
- {
- case T1B:
- f = f1b;
- *sel_vals = ftint (t, *sel_vals, &b1, &b2, size1b);
- nb1 = nb2 = size1b;
- break;
- case T2B:
- f = f2b;
- *sel_vals = ftint (t, *sel_vals, &b1, &b2, size2b);
- nb1 = nb2 = size2b;
- break;
- case T4B:
- f = f4b;
- *sel_vals = ftint (t, *sel_vals, &b1, &b2, size4b);
- nb1 = nb2 = size4b;
- break;
- case TFL:
- f = ffloat;
- *sel_vals = ftch (t, *sel_vals, &b1, &b2, &nb1, &nb2);
- tuple_value += size2b;
- tval_length -= size2b;
- break;
- case TCH:
- f = chcmp;
- *sel_vals = ftch (t, *sel_vals, &b1, &b2, &nb1, &nb2);
- tuple_value += size2b;
- tval_length -= size2b;
- break;
- case TFLOAT:
- f = flcmp;
- *sel_vals = ftint (t, *sel_vals, &b1, &b2, size4b);
- nb1 = nb2 = size4b;
- break;
- default:
- f = f1b;
- error ("TR.fcv:That data type isn't existence");
- break;
- }
-
- v = f (tuple_value, b1, tval_length, nb1);
-
- if (v == 0) /* current == first */
- res = (t == EQ || t == SES || t == SESE ||
- t == SMLEQ || t == GRTEQ) ? OK : NCR;
- else
- if (v > 0) /* current > first */
- if (BETWEEN_CMP)
- {
- v1 = f (tuple_value, b2, tval_length, nb2);
- if (v1 == 0) /* current == last */
- res = (t == SSE || t == SESE) ? OK : NCR;
- else
- res = (v1 > 0) ? NCR : OK;
- }
- else
- res = (t == NEQ || t == GRT || t == GRTEQ) ? OK : NCR;
- else /* current < first */
- res = (t == SML || t == SMLEQ || t == NEQ) ? OK : NCR;
-
- return res;
- }
- #undef BETWEEN_CMP
- int
- tstcsel (struct des_field *df, u2_t f_n, u2_t fdf, u2_t slsz, char *selc,
- char *tuple, char **arrpnt, u2_t *arrsz)
- {
- unsigned char t;
- i4_t sst;
- u2_t n = 0;
- char *sel_vals, *pnt;
- int tuple_size;
- tuple_size = tuple_break (tuple, arrpnt, arrsz, df, fdf, f_n);
- if (slsz == 0)
- return (tuple_size);
- sel_vals = selc;
- for (sst = 1; (t = selsc1 (&sel_vals, sst++)) != ENDSC;);
- if (sst % 2 == 0)
- sel_vals++;
- for (sst = 1; (t = selsc1 (&selc, sst++)) != ENDSC && n < f_n; n++)
- {
- if ((pnt = arrpnt[n]) == NULL) /* NULL VALUE */
- if(t != EQUN && t != ANY)
- return (0);
- else {}
- else
- if (fcv (t, (df + n)->field_type, &sel_vals, pnt, arrsz[n]) != OK)
- return (0);
- }
- return (tuple_size);
- }