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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  join.c  -  make up a join of two specific tables
  3.  *              Kernel of GNU SQL-server   
  4.  *
  5.  *  This file is a part of GNU SQL Server
  6.  *
  7.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  8.  *  Developed at the Institute of System Programming
  9.  *  This file is written by  Vera Ponomarenko
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24.  *
  25.  *  Contacts:   gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: join.c,v 1.246 1997/04/06 17:41:25 kml Exp $ */
  29. #include "xmem.h"
  30. #include "destrn.h"
  31. #include "strml.h"
  32. #include "fdcltrn.h"
  33. extern struct des_nseg desnseg;
  34. static u2_t k1;
  35. static char *sc;
  36. static int
  37. scale_frm (u2_t mfnsz, u2_t *mfn, char **arrpnt, u2_t *arrsz)
  38. {
  39.   u2_t i, fnk, size = 0, sz;
  40.   for (i = 0; i < mfnsz; i++)
  41.     {
  42.       fnk = mfn[i];
  43.       if ( arrpnt[fnk] != NULL )
  44. {
  45.   k1++;   
  46.   if ( (sz = arrsz[fnk]) != 0 )
  47.     size += sz;
  48. }
  49.     }
  50.   return (size);
  51. }
  52. static char *
  53. jncrtfrm (u2_t mfnsz, u2_t *mfn, char **arrpnt, u2_t *arrsz, char *val)
  54. {
  55.   u2_t fnk, i, k, sz;
  56.   char *b;
  57.   
  58.   k = 0;
  59.   for (i = 0; i < mfnsz; i++)
  60.     {
  61.       fnk = mfn[i];
  62.       if ( (b = arrpnt[fnk]) != NULL )
  63. {
  64.     *sc |= BITVL(k++); /* read 1 in key scale */
  65.     if (k == 7)
  66.       {
  67. k = 0;
  68. *(++sc) = 0;
  69.       }
  70.     if ( (sz = arrsz[fnk]) != 0 )
  71.               {
  72.                 bcopy (b, val, sz);
  73.                 val += sz;
  74.               }
  75. }
  76.     }  
  77.   return (val);
  78. }
  79. /*
  80.  * join relations
  81.  *
  82.  */
  83. struct ans_ctob
  84. join (struct id_rel *pir1, i4_t mfn1sz, u2_t *mfn1, struct id_rel *pir2,
  85.       i4_t mfn2sz, u2_t *mfn2)
  86. {
  87.   struct id_ob *pit1, *pit2;
  88.   struct des_tob *dt1, *dt2, *dt;
  89.   u2_t fn, fn1, fn2, fdf1, fdf2, kn1, kn2, *afn1, *afn2, fnk1, fnk2;
  90.   u2_t *ai1, *afi1, *ali1, *ai2, *afi2, *ali2, kk, type, kscsz, size;
  91.   struct des_trel *dtr1, *dtr2, *destrel;
  92.   struct des_field *df1, *df2, *df;
  93.   char *cort1, *cort2;
  94.   char *keyval;
  95.   char *asp1, *asp2;
  96.   struct A inpage1, inpage2, outpg;
  97.   i4_t drctn, d, v;
  98.   i2_t n;
  99.   struct ans_ctob ans;
  100.   char *arrpnt1[BD_PAGESIZE];
  101.   u2_t arrsz1[BD_PAGESIZE];
  102.   char *arrpnt2[BD_PAGESIZE];
  103.   u2_t arrsz2[BD_PAGESIZE];
  104.   pit1 = &pir1->urn;
  105.   pit2 = &pir2->urn;
  106.   if (pit1->segnum != NRSNUM || pit2->segnum != NRSNUM)
  107.     {
  108.       ans.cpncob = NIOB;
  109.       return (ans);
  110.     }
  111.   if ((u2_t) pit1->obnum > desnseg.mtobnum || (u2_t) pit2->obnum > desnseg.mtobnum)
  112.     {
  113.       ans.cpncob = NIOB;
  114.       return (ans);
  115.     }
  116.   dt1 = (struct des_tob *) * (desnseg.tobtab + pit1->obnum);
  117.   dt2 = (struct des_tob *) * (desnseg.tobtab + pit2->obnum);
  118.   if (dt1 == NULL || dt2 == NULL)
  119.     {
  120.       ans.cpncob = NIOB;
  121.       return (ans);
  122.     }    
  123.   if (dt1->prdt.prob != TREL || dt2->prdt.prob != TREL)
  124.     {
  125.       ans.cpncob = NDR;
  126.       return (ans);
  127.     }
  128.   if (dt1->prdt.prsort != SORT || dt2->prdt.prsort != SORT)
  129.     {
  130.       ans.cpncob = N_SORT;
  131.       return (ans);
  132.     }
  133.   if (dt1->prdt.prdbl != NODBL || dt2->prdt.prdbl != NODBL)
  134.     {
  135.       ans.cpncob = H_DBL;
  136.       return (ans);
  137.     }
  138.   if ((drctn = dt1->prdt.prdrctn) != dt2->prdt.prdrctn)
  139.     {
  140.       ans.cpncob = D_DRCTN;
  141.       return (ans);
  142.     }
  143.   dtr1 = (struct des_trel *) dt1;
  144.   dtr2 = (struct des_trel *) dt2;
  145.   fn1 = dtr1->fieldn;
  146.   fn2 = dtr2->fieldn;
  147.   kn1 = dtr1->keysntr;
  148.   kn2 = dtr2->keysntr;
  149.   fdf1 = dtr1->fdftr;
  150.   fdf2 = dtr2->fdftr;
  151.   df1 = (struct des_field *) (dtr1 + 1);
  152.   df2 = (struct des_field *) (dtr2 + 1);
  153. /* if(fn1!=fn2 || fdf1!=fdf2 || kn!=kn2) { ans.cpncob= N_EQV; return(ans); }*/
  154.   afn1 = (u2_t *) (df1 + fn1);
  155.   afn2 = (u2_t *) (df2 + fn2);
  156.   for (k1 = 0; k1 < kn1 && k1 < kn2; k1++)
  157.     {
  158.       fnk1 = *afn1++;
  159.       fnk2 = *afn2++;
  160.       if ((df1 + fnk1)->field_type != (df2 + fnk2)->field_type)
  161. {
  162.   ans.cpncob = N_EQV;
  163.   return (ans);
  164. }
  165.     }
  166.   fn = mfn1sz + mfn2sz;
  167.   dt = gettob (&outpg, dtrsize + fn * rfsize, &n, TREL);
  168.   destrel = (struct des_trel *) dt;
  169.   df = (struct des_field *) (destrel + 1);
  170.   asp1 = getwl (&inpage1, NRSNUM, dt1->firstpn);
  171.   afi1 = ai1 = (u2_t *) (asp1 + phtrsize);
  172.   ali1 = ai1 + ((struct p_h_tr *) asp1)->linptr;
  173.   asp2 = getwl (&inpage2, NRSNUM, dt2->firstpn);
  174.   afi2 = ai2 = (u2_t *) (asp2 + phtrsize);
  175.   ali2 = ai2 + ((struct p_h_tr *) asp2)->linptr;
  176.   if (drctn == GROW)
  177.     d = 1;
  178.   else
  179.     d = -1;
  180.   for (;;)
  181.     {
  182.       cort1 = getcort (&inpage1, &ai1);
  183.       if (cort1 == NULL)
  184. break;
  185.       cort2 = getcort (&inpage2, &ai2);
  186.       if (cort2 == NULL)
  187. break;
  188.       tuple_break (cort1, arrpnt1, arrsz1, df1, fdf1, fn1);
  189.       tuple_break (cort2, arrpnt2, arrsz2, df2, fdf2, fn2);
  190.   m1:
  191.       for (kk = 0; kk < kn1 && kk < kn2 ; kk++)
  192. {
  193.   fnk1 = afn1[kk];
  194.   type = (df1 + fnk1)->field_type;
  195.   fnk2 = afn2[kk];
  196.           v = cmpfv (type, d, arrpnt1[fnk1], arrpnt2[fnk2]);
  197.   if (v < 0)
  198.     {
  199.       cort1 = getcort (&inpage1, &ai1);
  200.       if (cort1 == NULL)
  201. goto m2;
  202.       tuple_break (cort1, arrpnt1, arrsz1, df1, fdf1, fn1);
  203.       goto m1;
  204.     }
  205.   else if (v > 0)
  206.     {
  207.       cort2 = getcort (&inpage2, &ai2);
  208.       if (cort2 == NULL)
  209. goto m2;
  210.       tuple_break (cort2, arrpnt2, arrsz2, df2, fdf2, fn2);     
  211.       goto m1;
  212.     }
  213. }
  214.       k1 = 0;
  215.       size = scale_frm (mfn1sz, mfn1, arrpnt1, arrsz1);
  216.       size += scale_frm (mfn2sz, mfn2, arrpnt2, arrsz2);      
  217.       kscsz = k1 / 7;
  218.       if ((k1 % 7) != 0)
  219. kscsz++;
  220.       size += kscsz + 1;
  221.       sc = getloc (&outpg, size, dt);
  222.       *sc++ = CORT;
  223.       keyval = sc + kscsz;
  224.       keyval = jncrtfrm (mfn1sz, mfn1, arrpnt1, arrsz1, keyval);
  225.       keyval = jncrtfrm (mfn2sz, mfn2, arrpnt2, arrsz2, keyval);
  226.       if ( (k1 % 7) == 0)
  227. sc--;
  228.       *sc |= EOSC;
  229.     }
  230. m2:
  231.   putwul (&outpg, 'm');
  232.   dt->prdt.prob = TREL;
  233.   dt->prdt.prsort = NSORT;
  234.   destrel->fieldn = fn;
  235.   destrel->fdftr = 0;
  236.   for ( v = 0; v < mfn1sz; v++)
  237.     *df++ = df1[mfn1[v]];
  238.   for ( v = 0; v < mfn2sz; v++)
  239.     *df++ = df2[mfn2[v]];  
  240.   ans.cpncob = OK;
  241.   ans.idob.segnum = NRSNUM;
  242.   ans.idob.obnum = n;
  243.   return (ans);
  244. }