📄 aggrifn.c
字号:
/* * aggrifn.c - calculation some aggregate functions * by specific table index * 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: aggrifn.c,v 1.247 1997/04/10 06:57:28 vera Exp $ */#include "xmem.h"#include "destrn.h"#include "agrflg.h"#include "strml.h"#include "fdcltrn.h"#include "cmpdecl.h"extern struct des_nseg desnseg;static voidagrmin (char *val1, char *val2, u2_t type, u2_t * n){ char *a; u2_t n2; a = val2; val2 += scscal (val2); if ((*a & BITVL(0)) != 0) { if (*val1 == 0) { *val1++ = 1; n2 = get_length (val2, type); bcopy (val2, val1, n2); *n = n2; } else { val1++; if (cmpval (val1, val2, type, &n2) > 0) { /* val2<val1 */ bcopy (val2, val1, n2); *n = n2; } } }}static u2_tfkv_frm (char *buf, char *val, u2_t type){ u2_t n; n = get_length (val, type); bcopy (val, buf, n); return (n);}static u2_tfkvfrm (char *buf, char *val, u2_t type){ if ((*val & BITVL(0)) == 0) { *buf = 0; return (1); } *buf++ = 1; val += scscal (val); return (fkv_frm (buf, val, type) + 1);}voidminitab (struct ans_next *ans, struct id_ind *pidind, u2_t slsz, char *sc, u2_t diasz, char *diasc){ u2_t sn, fn, fdf, pn, oldpn; struct des_field *df; struct ldesscan *disc; struct d_sc_i *scind; struct ldesind *di; struct d_r_t *desrel; char *value, *asp = NULL; struct id_rel *pidrel; struct des_tid tid; i4_t rep; i2_t n; u2_t *ai, *afi = NULL, type, *afn, kn, dscsz; struct A pg; pidrel = &pidind->irii; sn = pidrel->urn.segnum; if ((ans->cotnxt = cont_id (pidind, &desrel, &di)) != OK) return; fn = desrel->desrbd.fieldnum; fdf = desrel->desrbd.fdfnum; df = (struct des_field *) (desrel + 1); if ((ans->cotnxt = testcond (df, fn, fdf, 0, NULL, &slsz, sc, 0, NULL)) != OK) return; afn = (u2_t *) (di + 1); if ((ans->cotnxt = testdsc (desrel, &diasz, diasc, afn, &dscsz)) != OK) return; if ((ans->cotnxt = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != OK) return; kn = di->ldi.kifn & ~UNIQ & MSK21B; if ((ans->cotnxt = synlsc (RSC, pidrel, diasc, diasz, kn, afn)) != OK) return; 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; bcopy (diasc, asp + size2b, diasz); type = (df + *afn)->field_type; rep = ind_ftid (disc, &tid, FASTSCAN); value = ans->cadnxt; ans->csznxt = fkvfrm (value, disc->cur_key, type); oldpn = (u2_t) ~ 0; for (; rep != EOI; rep = ind_tid (disc, &tid, FASTSCAN)) { pn = tid.tpn; if (pn != oldpn) { if (oldpn != (u2_t) ~ 0) putpg (&pg, 'n'); while ((asp = getpg (&pg, sn, pn, 's')) == NULL); oldpn = pn; afi = (u2_t *) (asp + phsize); } ai = afi + tid.tindex; if (*ai != 0 && fndslc (desrel, asp, ai, sc, slsz, NULL) != 0) agrmin (value, disc->cur_key, type, &ans->csznxt); } putpg (&pg, 'n'); xfree (disc->cur_key); delscan (n);}static voidagrmax (char *val1, char *val2, u2_t type, u2_t * n){ char *a; u2_t n2; a = val2; val2 += scscal (val2); if ((*a & BITVL(0)) != 0) { if (*val1 == 0) { *val1++ = 1; n2 = get_length (val2, type); bcopy (val2, val1, n2); *n = n2; } else { val1++; if (cmpval (val1, val2, type, &n2) < 0) { /* val2>val1 */ bcopy (val2, val1, n2); *n = n2; } } }}voidmaxitab(struct ans_next *ans, struct id_ind *pidind, u2_t slsz, char *sc, u2_t diasz, char *diasc){ u2_t sn, fn, fdf, pn, oldpn; struct des_field *df; struct ldesscan *disc; struct d_sc_i *scind; struct ldesind *di; struct d_r_t *desrel; char *a, *asp = NULL; struct id_rel *pidrel; struct des_tid tid; i4_t rep; i2_t n; u2_t *ai, *afi = NULL, type, *afn, kn, dscsz; struct A pg; pidrel = &pidind->irii; sn = pidrel->urn.segnum; if ((ans->cotnxt = cont_id (pidind, &desrel, &di)) != OK) return; fn = desrel->desrbd.fieldnum; fdf = desrel->desrbd.fdfnum; df = (struct des_field *) (desrel + 1); if ((ans->cotnxt = testcond (df, fn, fdf, 0, NULL, &slsz, sc, 0, NULL)) != OK) return; afn = (u2_t *) (di + 1); if ((ans->cotnxt = testdsc (desrel, &diasz, diasc, afn, &dscsz)) != OK) return; if ((ans->cotnxt = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != OK) return; kn = di->ldi.kifn & ~UNIQ & MSK21B; if ((ans->cotnxt = synlsc (RSC, pidrel, diasc, diasz, kn, afn)) != OK) return; 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; bcopy (diasc, asp + size2b, diasz); type = (df + *afn)->field_type; rep = ind_ftid (disc, &tid, FASTSCAN); a = ans->cadnxt; ans->csznxt = fkvfrm (a, disc->cur_key, type); oldpn = (u2_t) ~ 0; for (; rep != EOI; rep = ind_tid (disc, &tid, FASTSCAN)) { pn = tid.tpn; if (pn != oldpn) { if (oldpn != (u2_t) ~ 0) putpg (&pg, 'n'); while ((asp = getpg (&pg, sn, pn, 's')) == NULL); oldpn = pn; afi = (u2_t *) (asp + phsize); } ai = afi + tid.tindex; if (*ai != 0 && fndslc (desrel, asp, ai, sc, slsz, NULL) != 0) agrmax (a, disc->cur_key, type, &ans->csznxt); } putpg (&pg, 'n'); xfree (disc->cur_key); delscan (n); return;}intcmpval (char *val1, char *val2, u2_t type, u2_t * n){ u2_t n1, n2; switch (type) { case T1B: *n = size1b; return (f1b (val1, val2, size1b, size1b)); case T2B: *n = size2b; return (f2b (val1, val2, size2b, size2b)); case T4B: *n = size4b; return (f4b (val1, val2, size4b, size4b)); case TFLOAT: *n = size4b; return (flcmp (val1, val2, size4b, size4b)); case TFL: n1 = t2bunpack (val1); val1 += size2b; n2 = t2bunpack (val2); val2 += size2b; *n = n2 + size2b; return (ffloat (val1, val2, n1, n2)); case TCH: n1 = t2bunpack (val1); val1 += size2b; n2 = t2bunpack (val2); val2 += size2b; *n = n2 + size2b; return (chcmp (val1, val2, n1, n2)); default: error ("TRN.cmpval: This data type is incorrect"); break; } return (0);}voidagrfind (struct ans_next *ans, struct id_ind *pidind, u2_t nf, u2_t * mnf, u2_t slsz, char *sc, u2_t diasz, char *diasc, char *flaglist){ u2_t i, fn, fdf, pn, oldpn, sn; struct des_field *df; struct ldesscan *disc; struct d_sc_i *scind; struct ldesind *di; struct d_r_t *desrel; char **agrl, *asp = NULL; struct id_rel *pidrel; struct des_tid tid; struct A pg; i4_t rep; i2_t n; u2_t *ai, *afi = NULL, *afn, kn, dscsz; pidrel = &pidind->irii; sn = pidrel->urn.segnum; if ((ans->cotnxt = cont_id (pidind, &desrel, &di)) != OK) return; fn = desrel->desrbd.fieldnum; fdf = desrel->desrbd.fdfnum; df = (struct des_field *) (desrel + 1); if ((ans->cotnxt = testcond (df, fn, fdf, 0, NULL, &slsz, sc, 0, NULL)) != OK) return; afn = (u2_t *) (di + 1); if ((ans->cotnxt = testdsc (desrel, &diasz, diasc, afn, &dscsz)) != OK) return; if ((ans->cotnxt = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != OK) return; kn = di->ldi.kifn & ~UNIQ & MSK21B; if ((ans->cotnxt = synlsc (RSC, pidrel, diasc, diasz, kn, afn)) != OK) return; 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; bcopy (diasc, asp + size2b, diasz); rep = ind_ftid (disc, &tid, FASTSCAN); if (rep == EOI) i = 0; else i = 1; agrl = (char **) xmalloc (nf * sizeof (char *)); agrl_frm (agrl, df, (u2_t) nf, mnf, flaglist);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -