📄 aggravg.c
字号:
/* * 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 intagravg (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_avgavgitab (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_avgavgstab (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_tfndslc (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 intfcv (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_CMPinttstcsel (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);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -