aggrifn.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:17k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  * aggrifn.c  - calculation some aggregate functions
  3.  *               by specific table index
  4.  *              Kernel of GNU SQL-server 
  5.  *
  6.  * This file is a part of GNU SQL Server
  7.  *
  8.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  9.  *  Developed at the Institute of System Programming
  10.  *  This file is written by  Vera Ponomarenko
  11.  *
  12.  *  This program is free software; you can redistribute it and/or modify
  13.  *  it under the terms of the GNU General Public License as published by
  14.  *  the Free Software Foundation; either version 2 of the License, or
  15.  *  (at your option) any later version.
  16.  *
  17.  *  This program is distributed in the hope that it will be useful,
  18.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  *  GNU General Public License for more details.
  21.  *
  22.  *  You should have received a copy of the GNU General Public License
  23.  *  along with this program; if not, write to the Free Software
  24.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25.  *
  26.  *  Contacts:   gss@ispras.ru
  27.  *
  28.  */
  29. /* $Id: aggrifn.c,v 1.247 1997/04/10 06:57:28 vera Exp $ */
  30. #include "xmem.h"
  31. #include "destrn.h"
  32. #include "agrflg.h"
  33. #include "strml.h"
  34. #include "fdcltrn.h"
  35. #include "cmpdecl.h"
  36. extern struct des_nseg desnseg;
  37. static void
  38. agrmin (char *val1, char *val2, u2_t type, u2_t * n)
  39. {
  40.   char *a;
  41.   u2_t n2;
  42.   a = val2;
  43.   val2 += scscal (val2);
  44.   if ((*a & BITVL(0)) != 0)
  45.     {
  46.       if (*val1 == 0)
  47. {
  48.   *val1++ = 1;
  49.   n2 = get_length (val2, type);
  50.           bcopy (val2, val1, n2);
  51.   *n = n2;
  52. }
  53.       else
  54. {
  55.   val1++;
  56.   if (cmpval (val1, val2, type, &n2) > 0)
  57.     { /* val2<val1 */
  58.               bcopy (val2, val1, n2);
  59.       *n = n2;
  60.     }
  61. }
  62.     }
  63. }
  64. static u2_t
  65. fkv_frm (char *buf, char *val, u2_t type)
  66. {
  67.   u2_t n;
  68.   
  69.   n = get_length (val, type);
  70.   bcopy (val, buf, n);
  71.   return (n);
  72. }
  73. static u2_t
  74. fkvfrm (char *buf, char *val, u2_t type)
  75. {
  76.   if ((*val & BITVL(0)) == 0)
  77.     {
  78.       *buf = 0;
  79.       return (1);
  80.     }
  81.   *buf++ = 1;
  82.   val += scscal (val);
  83.   return (fkv_frm (buf, val, type) + 1);
  84. }
  85. void
  86. minitab (struct ans_next *ans, struct id_ind *pidind, u2_t slsz,
  87.          char *sc, u2_t diasz, char *diasc)
  88. {
  89.   u2_t sn, fn, fdf, pn, oldpn;
  90.   struct des_field *df;
  91.   struct ldesscan *disc;
  92.   struct d_sc_i *scind;
  93.   struct ldesind *di;
  94.   struct d_r_t *desrel;
  95.   char *value, *asp = NULL;
  96.   struct id_rel *pidrel;
  97.   struct des_tid tid;
  98.   i4_t rep;
  99.   i2_t n;
  100.   u2_t *ai, *afi = NULL, type, *afn, kn, dscsz;
  101.   struct A pg;
  102.   pidrel = &pidind->irii;
  103.   sn = pidrel->urn.segnum;
  104.   if ((ans->cotnxt = cont_id (pidind, &desrel, &di)) != OK)
  105.     return;
  106.   fn = desrel->desrbd.fieldnum;
  107.   fdf = desrel->desrbd.fdfnum;
  108.   df = (struct des_field *) (desrel + 1);
  109.   if ((ans->cotnxt = testcond (df, fn, fdf, 0, NULL,
  110.                                &slsz, sc, 0, NULL)) != OK)
  111.     return;
  112.   afn = (u2_t *) (di + 1);
  113.   if ((ans->cotnxt = testdsc (desrel, &diasz, diasc, afn, &dscsz)) != OK)
  114.     return;
  115.   if ((ans->cotnxt = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != OK)
  116.     return;
  117.   kn = di->ldi.kifn & ~UNIQ & MSK21B;
  118.   if ((ans->cotnxt = synlsc (RSC, pidrel, diasc, diasz, kn, afn)) != OK)
  119.     return;
  120.   scind = (struct d_sc_i *) lusc (&n, scisize, (char *) di, SCI, RSC,
  121.                                   0, NULL, sc, slsz,
  122.   0, NULL, diasz + size2b);
  123.   disc = &scind->dessc;
  124.   disc->pdi = di;
  125.   disc->curlpn = (u2_t) ~ 0;
  126.   asp = (char *) (scind + 1) + slsz + size2b;
  127.   if (diasz == 0)
  128.     disc->dpnsc = NULL;
  129.   else
  130.     disc->dpnsc = asp;
  131.   t2bpack (diasz, asp);
  132.   disc->dpnsval = asp + size2b + dscsz;
  133.   bcopy (diasc, asp + size2b, diasz);
  134.   type = (df + *afn)->field_type;
  135.   rep = ind_ftid (disc, &tid, FASTSCAN);
  136.   value = ans->cadnxt;
  137.   ans->csznxt = fkvfrm (value, disc->cur_key, type);
  138.   oldpn = (u2_t) ~ 0;
  139.   for (; rep != EOI; rep = ind_tid (disc, &tid, FASTSCAN))
  140.     {
  141.       pn = tid.tpn;
  142.       if (pn != oldpn)
  143. {
  144.   if (oldpn != (u2_t) ~ 0)
  145.     putpg (&pg, 'n');
  146.   while ((asp = getpg (&pg, sn, pn, 's')) == NULL);
  147.   oldpn = pn;
  148.   afi = (u2_t *) (asp + phsize);
  149. }
  150.       ai = afi + tid.tindex;
  151.       if (*ai != 0 && fndslc (desrel, asp, ai, sc, slsz, NULL) != 0)
  152. agrmin (value, disc->cur_key, type, &ans->csznxt);
  153.     }
  154.   putpg (&pg, 'n');
  155.   xfree (disc->cur_key);
  156.   delscan (n);
  157. }
  158. static void
  159. agrmax (char *val1, char *val2, u2_t type, u2_t * n)
  160. {
  161.   char *a;
  162.   u2_t n2;
  163.   a = val2;
  164.   val2 += scscal (val2);
  165.   if ((*a & BITVL(0)) != 0)
  166.     {
  167.       if (*val1 == 0)
  168. {
  169.   *val1++ = 1;
  170.   n2 = get_length (val2, type);
  171.           bcopy (val2, val1, n2);
  172.   *n = n2;
  173. }
  174.       else
  175. {
  176.   val1++; 
  177.   if (cmpval (val1, val2, type, &n2) < 0)
  178.     { /* val2>val1 */
  179.               bcopy (val2, val1, n2);
  180.       *n = n2;
  181.     }
  182. }
  183.     }
  184. }
  185. void
  186. maxitab(struct ans_next *ans, struct id_ind *pidind,
  187.         u2_t slsz, char *sc, u2_t diasz, char *diasc)
  188. {
  189.   u2_t sn, fn, fdf, pn, oldpn;
  190.   struct des_field *df;
  191.   struct ldesscan *disc;
  192.   struct d_sc_i *scind;
  193.   struct ldesind *di;
  194.   struct d_r_t *desrel;
  195.   char *a, *asp = NULL;
  196.   struct id_rel *pidrel;
  197.   struct des_tid tid;
  198.   i4_t rep;
  199.   i2_t n;
  200.   u2_t *ai, *afi = NULL, type, *afn, kn, dscsz;
  201.   struct A pg;
  202.   pidrel = &pidind->irii;
  203.   sn = pidrel->urn.segnum;
  204.   if ((ans->cotnxt = cont_id (pidind, &desrel, &di)) != OK)
  205.     return;
  206.   fn = desrel->desrbd.fieldnum;
  207.   fdf = desrel->desrbd.fdfnum;
  208.   df = (struct des_field *) (desrel + 1);
  209.   if ((ans->cotnxt = testcond (df, fn, fdf, 0, NULL,
  210.                                &slsz, sc, 0, NULL)) != OK)
  211.     return;
  212.   afn = (u2_t *) (di + 1);
  213.   if ((ans->cotnxt = testdsc (desrel, &diasz, diasc, afn, &dscsz)) != OK)
  214.     return;
  215.   if ((ans->cotnxt = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != OK)
  216.     return;
  217.   kn = di->ldi.kifn & ~UNIQ & MSK21B;
  218.   if ((ans->cotnxt = synlsc (RSC, pidrel, diasc, diasz, kn, afn)) != OK)
  219.     return;
  220.   scind = (struct d_sc_i *) lusc (&n, scisize, (char *) di, SCI, RSC,
  221.                                   0, NULL, sc, slsz,
  222.   0, NULL, diasz + size2b);
  223.   disc = &scind->dessc;
  224.   disc->pdi = di;
  225.   disc->curlpn = (u2_t) ~ 0;
  226.   asp = (char *) (scind + 1) + slsz + size2b;
  227.   if (diasz == 0)
  228.     disc->dpnsc = NULL;
  229.   else
  230.     disc->dpnsc = asp;
  231.   t2bpack (diasz, asp);
  232.   disc->dpnsval = asp + size2b + dscsz;
  233.   bcopy (diasc, asp + size2b, diasz);
  234.   type = (df + *afn)->field_type;
  235.   rep = ind_ftid (disc, &tid, FASTSCAN);
  236.   a = ans->cadnxt;
  237.   ans->csznxt = fkvfrm (a, disc->cur_key, type);
  238.   oldpn = (u2_t) ~ 0;
  239.   for (; rep != EOI; rep = ind_tid (disc, &tid, FASTSCAN))
  240.     {
  241.       pn = tid.tpn;
  242.       if (pn != oldpn)
  243. {
  244.   if (oldpn != (u2_t) ~ 0)
  245.     putpg (&pg, 'n');
  246.   while ((asp = getpg (&pg, sn, pn, 's')) == NULL);
  247.   oldpn = pn;
  248.           afi = (u2_t *) (asp + phsize);
  249. }
  250.       ai = afi + tid.tindex;
  251.       if (*ai != 0 && fndslc (desrel, asp, ai, sc, slsz, NULL) != 0)
  252. agrmax (a, disc->cur_key, type, &ans->csznxt);
  253.     }
  254.   putpg (&pg, 'n');
  255.   xfree (disc->cur_key);
  256.   delscan (n);
  257.   return;
  258. }
  259. int
  260. cmpval (char *val1, char *val2, u2_t type, u2_t * n)
  261. {
  262.   u2_t n1, n2;
  263.   
  264.   switch (type)
  265.     {
  266.     case T1B:
  267.       *n = size1b;
  268.       return (f1b (val1, val2, size1b, size1b));
  269.     case T2B:
  270.       *n = size2b;
  271.       return (f2b (val1, val2, size2b, size2b));
  272.     case T4B:
  273.       *n = size4b;
  274.       return (f4b (val1, val2, size4b, size4b));
  275.     case TFLOAT:
  276.       *n = size4b;
  277.       return (flcmp (val1, val2, size4b, size4b));
  278.     case TFL:
  279.       n1 = t2bunpack (val1);
  280.       val1 += size2b;
  281.       n2 = t2bunpack (val2);
  282.       val2 += size2b;
  283.       *n = n2 + size2b;
  284.       return (ffloat (val1, val2, n1, n2));
  285.     case TCH:
  286.       n1 = t2bunpack (val1);
  287.       val1 += size2b;
  288.       n2 = t2bunpack (val2);
  289.       val2 += size2b;
  290.       *n = n2 + size2b;
  291.       return (chcmp (val1, val2, n1, n2));
  292.     default:
  293.       error ("TRN.cmpval: This data type is incorrect");
  294.       break;
  295.     }
  296.   return (0);
  297. }
  298. void
  299. agrfind (struct ans_next *ans, struct id_ind *pidind, u2_t nf,
  300.          u2_t * mnf, u2_t slsz, char *sc, u2_t diasz,
  301.          char *diasc, char *flaglist)
  302. {
  303.   u2_t i, fn, fdf, pn, oldpn, sn;
  304.   struct des_field *df;
  305.   struct ldesscan *disc;
  306.   struct d_sc_i *scind;
  307.   struct ldesind *di;
  308.   struct d_r_t *desrel;
  309.   char **agrl, *asp = NULL;
  310.   struct id_rel *pidrel;
  311.   struct des_tid tid;
  312.   struct A pg;
  313.   i4_t rep;
  314.   i2_t n;
  315.   u2_t *ai, *afi = NULL, *afn, kn, dscsz;
  316.   pidrel = &pidind->irii;
  317.   sn = pidrel->urn.segnum;
  318.   if ((ans->cotnxt = cont_id (pidind, &desrel, &di)) != OK)
  319.     return;
  320.   fn = desrel->desrbd.fieldnum;
  321.   fdf = desrel->desrbd.fdfnum;
  322.   df = (struct des_field *) (desrel + 1);
  323.   if ((ans->cotnxt = testcond (df, fn, fdf, 0, NULL, &slsz, sc,
  324.                                0, NULL)) != OK)
  325.     return;
  326.   afn = (u2_t *) (di + 1);
  327.   if ((ans->cotnxt = testdsc (desrel, &diasz, diasc, afn, &dscsz)) != OK)
  328.     return;
  329.   if ((ans->cotnxt = synlsc (RSC, pidrel, sc, slsz, fn, (u2_t *) NULL)) != OK)
  330.     return;
  331.   kn = di->ldi.kifn & ~UNIQ & MSK21B;
  332.   if ((ans->cotnxt = synlsc (RSC, pidrel, diasc, diasz, kn, afn)) != OK)
  333.     return;
  334.   scind = (struct d_sc_i *) lusc (&n, scisize, (char *) di, SCI, RSC,
  335.                                   0, NULL, sc, slsz,
  336.   0, NULL, diasz + size2b);
  337.   disc = &scind->dessc;
  338.   disc->pdi = di;
  339.   disc->curlpn = (u2_t) ~ 0;
  340.   asp = (char *) (scind + 1) + slsz + size2b;
  341.   if (diasz == 0)
  342.     disc->dpnsc = NULL;
  343.   else
  344.     disc->dpnsc = asp;
  345.   t2bpack (diasz, asp);
  346.   disc->dpnsval = asp + size2b + dscsz;
  347.   bcopy (diasc, asp + size2b, diasz);
  348.   rep = ind_ftid (disc, &tid, FASTSCAN);
  349.   if (rep == EOI)
  350.     i = 0;
  351.   else
  352.     i = 1;
  353.   agrl = (char **) xmalloc (nf * sizeof (char *));
  354.   agrl_frm (agrl, df, (u2_t) nf, mnf, flaglist);
  355.   oldpn = (u2_t) ~ 0;
  356.   for (; rep != EOI; rep = ind_tid (disc, &tid, FASTSCAN))
  357.     {
  358.       pn = tid.tpn;
  359.       if (pn != oldpn)
  360. {
  361.   if (oldpn != (u2_t) ~ 0)
  362.     putpg (&pg, 'n');
  363.   while((asp = getpg (&pg, sn, pn, 's')) == NULL);
  364.   oldpn = pn;
  365.   afi = (u2_t *) (asp + phsize);
  366. }
  367.       ai = afi + tid.tindex;
  368.       if (*ai != 0 &&
  369.           fndslc (desrel, asp, ai, sc, slsz, NULL) != 0)
  370. agrcount (agrl, asp + *ai, df, fdf, fn, nf, mnf, flaglist);
  371.     }
  372.   if (i == 1)
  373.     {
  374.       putpg (&pg, 'n');
  375.       xfree (disc->cur_key);
  376.       distagr_frm (agrl, nf, flaglist);
  377.     }
  378.   ans->csznxt = write_val (ans->cadnxt, agrl, df, nf, mnf, flaglist);
  379.   for (i = 0; i < nf; i++)
  380.     xfree (agrl[i]);
  381.   xfree ((char *) agrl);
  382.   delscan (n);
  383.   return;
  384. }
  385. #if 0
  386. void
  387. ffrm_agrcount (char **agrl, char *tuple, struct des_field *df,
  388.                u2_t fdf, u2_t f_n, u2_t nf, u2_t * mnf, char *flaglist)
  389. {
  390.   char *val;
  391.   u2_t kn, fn;
  392.   char *arrpnt[BD_PAGESIZE];
  393.   u2_t arrsz[BD_PAGESIZE];
  394.   tuple_break (tuple, arrpnt, arrsz, df, fdf, f_n);
  395.   for (kn = 0; kn < nf; kn++)
  396.     {
  397.       fn = mnf[kn];
  398.       if ((val = arrpnt[fn]) != NULL)
  399. agr_ffrm (agrl[kn], flaglist[kn], val, (df + fn)->field_type);
  400.     }
  401. }
  402. void
  403. agr_ffrm (char *agrl, char flag, char *val, u2_t type)
  404. {
  405.   char *a, *b, *c;
  406.   i4_t count;
  407.   float avg;
  408.   switch (flag)
  409.     {
  410.     case FN_COUNT:
  411.       count = 1;
  412.       t4bpack (count, agrl);
  413.       break;
  414.     case FN_AVG:
  415.       count = 1;
  416.       avg = retval (val, type);
  417.       bcopy ((char *) &avg, agrl, sizeof (float));
  418.       t4bpack (count, agrl + sizeof (float));
  419.       break;
  420.     case FN_MAX:
  421.     case FN_MIN:
  422.     case FN_SUMM:
  423.       fkv_frm (agrl, val, type);
  424.       break;
  425.     case FN_DT_COUNT:
  426.     case FN_DT_AVG:
  427.     case FN_DT_SUMM:
  428.       val = agr_dt_cfrm (val, type, agrl);
  429.       break;
  430.     default:
  431.       break;
  432.     }
  433. }
  434. #endif
  435. static float
  436. retval (char *val, u2_t type)
  437. {
  438.   float flval;
  439.   switch (type)
  440.     {
  441.     case T1B:
  442.       flval = *val;
  443.       break;
  444.     case T2B:
  445.       flval = t2bunpack (val);
  446.       break;
  447.     case TFLOAT:
  448.       bcopy (val, (char *) &flval, size4b);
  449.       break;
  450.     case T4B:
  451.       flval = t4bunpack (val);
  452.       break;
  453.     default:
  454.       error ("TRN.retval: This data type is incorrect");
  455.       break;
  456.     }
  457.   return (flval);
  458. }
  459. void
  460. agrcount (char **agrl, char *tuple, struct des_field *df,
  461.           u2_t fdf, u2_t f_n, u2_t nf, u2_t * mnf, char *flaglist)
  462. {
  463.   u2_t kn, fn;
  464.   char *arrpnt[BD_PAGESIZE];
  465.   u2_t arrsz[BD_PAGESIZE];
  466.   tuple_break (tuple, arrpnt, arrsz, df, fdf, f_n);
  467.   for (kn = 0; kn < nf; kn++)
  468.     {
  469.       fn = mnf[kn];
  470.       agr_frm (agrl[kn], flaglist[kn], arrpnt[fn], (df + fn)->field_type);
  471.     }
  472. }
  473. static char *
  474. agr_dt_cfrm (char *val, u2_t type, char *agrl)
  475. {
  476.   char *newt, *outasp, mch[BD_PAGESIZE];
  477.   struct des_tob *dt;
  478.   i2_t n;
  479.   u2_t corsize;
  480.   struct A pg;
  481.   newt = mch;
  482.   *newt = 0;
  483.   *newt |= EOSC;
  484.   if ( val != NULL)
  485.     {
  486.       *newt |= BITVL(0);
  487.       newt++;
  488.       val = remval (val, &newt, type);
  489.     }
  490.   else
  491.     newt++;
  492.   corsize = newt - mch;
  493.   n = t2bunpack (agrl);
  494.   dt = (struct des_tob *) * (desnseg.tobtab + n);
  495.   outasp = getwl (&pg, NRSNUM, dt->lastpn);
  496.   minstr (&pg, mch, corsize, dt);
  497.   putwul (&pg, 'm');
  498.   return (val);
  499. }
  500. static void
  501. sumfld (char *buf, char *val, u2_t type)
  502. {
  503.   u2_t val2, sum2;
  504.   i4_t val4, sum4;
  505.   float fval, sumf;
  506.   switch (type)
  507.     {
  508.     case T1B:
  509.       *buf += *val;
  510.       break;
  511.     case T2B:
  512.       val2 = t2bunpack (val);
  513.       sum2 = t2bunpack (buf) + val2;
  514.       t2bpack (sum2, buf);
  515.       break;
  516.     case T4B:
  517.       val4 = t4bunpack (val);
  518.       sum4 = t4bunpack (buf) + val4;
  519.       t4bpack (sum4, buf);
  520.       break;
  521.     case TFLOAT:
  522.       bcopy (buf, (char *) &sumf, size4b);
  523.       bcopy (val, (char *) &fval, size4b);
  524.       sumf += fval;
  525.       bcopy ((char *) &sumf, buf, size4b);
  526.       break;
  527.     default:
  528.       error ("TRN.sumfld: This data type is incorrect");
  529.       break;
  530.     }
  531. }
  532. static i4_t
  533. avgfld (float *avg, i4_t n_avg, u2_t type, char *fval)
  534. {
  535.   float val;
  536.   val = retval (fval, type);
  537.   *avg = ((*avg) * n_avg + val) / (n_avg + 1);
  538.   n_avg += 1;
  539.   return (n_avg);
  540. }
  541. void
  542. agr_frm (char *agrl, i4_t flag, char *val, u2_t type)
  543. {
  544.   char *b;
  545.   u2_t n;
  546.   float avg;
  547.   i4_t count;
  548.   switch (flag)
  549.     {
  550.     case FN_COUNT:
  551.       if (val != NULL)
  552. {
  553.   agrl++;
  554.   count = t4bunpack (agrl);
  555.   count += 1;
  556.   t4bpack (count, agrl);
  557. }
  558.       break;
  559.     case FN_SUMM:
  560.       if (val != NULL)
  561. {
  562.   *agrl++ = 1;      
  563.   sumfld (agrl, val, type);
  564. }
  565.       break;      
  566.     case FN_MAX:
  567.       if (val != NULL)
  568. {
  569.   if (*agrl == 0)
  570.     {
  571.       *agrl++ = 1;
  572.       n = get_length (val, type);
  573.               bcopy (val, agrl, n);
  574.     }
  575.   else
  576.     {
  577.       agrl++;
  578.       if (cmpval (agrl, val, type, &n) < 0) /* val2>val1 */
  579.                 bcopy (val, agrl, n);
  580.     }
  581. }
  582.       break;
  583.     case FN_MIN:
  584.       if (val != NULL)
  585. {
  586.   if (*agrl == 0)
  587.     {
  588.       *agrl++ = 1;
  589.       n = get_length (val, type);
  590.               bcopy (val, agrl, n);
  591.     }
  592.   else
  593.     {
  594.       agrl++;      
  595.       if (cmpval (agrl, val, type, &n) > 0) /* val2<val1 */
  596.                 bcopy (val, agrl, n);
  597.     }
  598. }
  599.       break;
  600.     case FN_AVG:
  601.       if (val != NULL)
  602. {
  603.   *agrl++ = 1;
  604.           bcopy (agrl, (char *) &avg, sizeof (float));
  605.           b = agrl + sizeof (float);
  606.   count = t4bunpack (b);
  607.   count = avgfld (&avg, count, type, val);
  608.           bcopy ((char *) &avg, agrl, sizeof (float));
  609.   t4bpack (count, b);
  610. }
  611.       break;      
  612.     case FN_DT_COUNT:
  613.     case FN_DT_AVG:
  614.     case FN_DT_SUMM:
  615.       val = agr_dt_cfrm (val, type, agrl);
  616.       break;
  617.     default:
  618.       break;
  619.     }
  620. }
  621. int
  622. write_val (char *mas, char **agrl, struct des_field *df,
  623.            u2_t nf, u2_t * mnf, char *flaglist)
  624. {
  625.   char *b, *sc, *pnt;
  626.   u2_t k, type;
  627.   u2_t size;
  628.   sc = mas;
  629.   pnt = sc + nf;
  630.   for (k = 0; k < nf; k++)
  631.     {
  632.       b = agrl[k];      
  633.       switch (flaglist[k])
  634. {
  635. case FN_DT_COUNT:
  636.           b += size2b; /* skip tmptable id */
  637. case FN_COUNT:
  638.   *sc++ = *b++;
  639.   t2bpack (size4b, pnt);
  640.   pnt += size2b;
  641.           bcopy (b, pnt, size4b);
  642.           pnt += size4b;
  643.   break;
  644. case FN_DT_AVG:
  645.           b += size2b; /* skip tmptable id */
  646. case FN_AVG:
  647.   *sc++ = *b++;
  648.   t2bpack (size4b, pnt);
  649.   pnt += size2b;   
  650.           pnt = write_average (TFLOAT, b, pnt);
  651.   break;
  652. case FN_DT_SUMM:
  653.           b += size2b; /* skip tmptable id */
  654. case FN_MAX:
  655. case FN_MIN:
  656. case FN_SUMM:
  657.   *sc++ = *b++;
  658.   type = (df + mnf[k])->field_type;
  659.   if (type == TCH || type == TFL)
  660.     {
  661.       size = t2bunpack (b);
  662.       b += size2b;
  663.     }
  664.   else
  665.     size = (df + mnf[k])->field_size;
  666.   t2bpack (size, pnt);
  667.   pnt += size2b;
  668.           bcopy (b, pnt, size);
  669.           pnt += size;
  670.   break;
  671. default:
  672.   break;
  673. }
  674.     }
  675.   return (pnt - mas);
  676. }
  677. char *
  678. write_average (u2_t type, char *pnt_from, char *pnt_to)
  679. {
  680.   u2_t avrg2;
  681.   i4_t avrg4;
  682.   float avrg;
  683.   bcopy (pnt_from, (char *) &avrg, sizeof (float));
  684.   if (type == T1B)
  685.     *pnt_to++ = (i1_t) avrg;
  686.   else if (type == T2B)
  687.     {
  688.       avrg2 = (u2_t) avrg;
  689.       t2bpack (avrg2, pnt_to);
  690.       pnt_to += size2b;
  691.     }
  692.   else if (type == T4B)
  693.     {
  694.       avrg4 = (i4_t) avrg;
  695.       t4bpack (avrg4, pnt_to);
  696.       pnt_to += size4b;
  697.     }
  698.   else if (type == TFLOAT)
  699.     {
  700.       bcopy ((char *) &avrg, pnt_to, sizeof (float));
  701.       pnt_to += sizeof (float);
  702.     }
  703.   return (pnt_to);
  704. }