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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  rllbfn.c  - Rollback Functions 
  3.  *
  4.  *  This file is a part of GNU SQL Server
  5.  *
  6.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  7.  *  Developed at the Institute of System Programming
  8.  *  This file is written by  Vera Ponomarenko
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  *
  24.  *  Contacts:   gss@ispras.ru
  25.  *
  26.  */
  27. /* $Id: rllbfn.c,v 1.249 1997/04/17 11:03:20 vera Exp $ */ 
  28. #include "xmem.h"
  29. #include "destrn.h"
  30. #include "strml.h"
  31. #include "fdcltrn.h"
  32. #include "totdecl.h"
  33. #include <assert.h>
  34. extern struct d_r_t *firstrel;
  35. extern i2_t maxscan;
  36. extern char **scptab;
  37. #define INDEX_PTR(table_tuple_ptr,table_descriptor_ptr) 
  38.   (table_tuple_ptr + scscal (table_tuple_ptr) + drbdsize + table_descriptor_ptr->desrbd.fieldnum * rfsize)
  39. /*
  40.  * redo relation tuple deletion
  41.  */
  42. void
  43. redo_dltn (u2_t sn, struct d_r_t *desrel, i4_t rn,
  44.            struct des_tid *tid, u2_t n, char *a)
  45. {
  46.   i4_t ordrn;
  47.   struct des_tid ref_tid;
  48.   ref_tid.tpn = (u2_t) ~ 0;
  49.   orddel (sn, rn, tid, &ref_tid, n);
  50.   if (rn != RDRNUM)
  51.     {
  52.       proind (ordindd, desrel, desrel->desrbd.indnum, a, tid);
  53.       return;
  54.     }
  55.   /* else */
  56.   ordrn = t4bunpack (a + scscal (a));
  57.       
  58.   /* find relation descriptor */
  59.   for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist)
  60.     if (desrel->desrbd.relnum == ordrn)
  61.       break;
  62.       
  63.   if (desrel == NULL)           /* if descrel not found  */
  64.     return;                     /* just return - but it looks strange -- may be we should produce warning ?? */
  65.   /* delete all indexes, defined on given table */
  66.   while ( desrel->pid != NULL )
  67.     {
  68.       struct ldesind *di;
  69.       di = desrel->pid;
  70.       desrel->pid = di->listind;
  71.       delscd (di->oscni, (char *) di);
  72.       killind (di);
  73.       xfree ((void *) di);
  74.     }
  75.       
  76.   delscd (desrel->oscnum, (char *) desrel);
  77.   /* remove desrel from list */
  78.   if (desrel == firstrel)
  79.     firstrel = desrel->drlist;
  80.   else
  81.     {
  82.       struct d_r_t *dr;
  83.       for (dr = firstrel; dr->drlist != desrel; dr = dr->drlist);
  84.       assert( dr->drlist == desrel );
  85.       dr->drlist = desrel->drlist;
  86.     }
  87.   xfree ((void *) desrel);
  88. }
  89. /*
  90.  * redo tuple insertation
  91.  */
  92. void
  93. redo_insrtn (u2_t sn, struct d_r_t *desrel, i4_t rn,
  94.              struct des_tid *tid, i2_t n, char *a)
  95. {
  96.   if (nordins (sn, rn, tid, CORT, MIN_TUPLE_LENGTH, n, a) != 0)
  97.     doindir (sn, rn, tid, MIN_TUPLE_LENGTH, n, a);
  98.   if (rn != RDRNUM)
  99.     proind (ordindi, desrel, desrel->desrbd.indnum, a, tid);
  100.   else
  101.     {
  102.       i4_t ordrn;
  103.       struct d_r_t *desrel1;
  104.       struct ldesind *di;
  105.       struct id_rel idr;
  106.       
  107.       ordrn = t4bunpack (a + scscal (a));
  108.       idr.urn.segnum = sn;
  109.       idr.urn.obnum = ordrn;
  110.       idr.pagenum = tid->tpn;
  111.       idr.index = tid->tindex;
  112.       desrel1 = crtfrd (&idr, a);
  113.       for (di = desrel1->pid; di != NULL; di = di->listind)
  114. crindci (di);
  115.     }
  116. }
  117. /*
  118.  * redo "delete index" operation.
  119.  *
  120.  * DESCREL point to present relation structure b_e_f_o_r_e deletion operation
  121.  * NEW_TABLE_TUPLE points to new descriptor tuple a_f_t_e_r modification
  122.  *
  123.  * this function compares index description prior and after modification and
  124.  * executes all required operations to tranform index structure
  125.  */
  126. void
  127. redo_dind (struct d_r_t *desrel, char *new_table_tuple)
  128. {
  129.   struct ldesind *di, *prdi;
  130.   char *pnt;
  131.   char *indexes_prt;
  132.   u2_t kn, indn, i;
  133.   indexes_prt =  INDEX_PTR(new_table_tuple,desrel);
  134.   
  135.   indn = desrel->desrbd.indnum - 1; /* (++) this function expect deletion of only one index */
  136.   
  137.   for (prdi = NULL, di = desrel->pid ;
  138.        di != NULL;
  139.        prdi = di, di = (di?di->listind:desrel->pid))
  140.     {                                             /* for every existent index   */
  141.       pnt = indexes_prt;                          
  142.       for (i = 0; i < indn; i++)                  /* scan  new table tuple      */
  143.           struct des_index desind;
  144.           
  145.   BUFUPACK(pnt,desind);                   /* unpack it indexes descr    */
  146.   kn = desind.kifn & ~UNIQ & MSK21B;      /* calculate number of keys   */
  147.   pnt += kn * size2b;                     /* and skip keys' descriptors */
  148.   if (desind.unindex == di->ldi.unindex)  /* if existent index is in    */
  149.             break;                                /* new tuple check another one*/
  150. }
  151.       if (i < indn)                               /* if current index has not   */
  152.         continue;                                 /* been removed goto next one */
  153.       /* current index WAS removed -- redo index deletion                       */
  154.       /* delete index from table list */
  155.       if (prdi == NULL)
  156. desrel->pid = di->listind;
  157.       else
  158. prdi->listind = di->listind;
  159.       desrel->desrbd.indnum--;
  160.       delscd (di->oscni, (char *) di);
  161.       killind (di);
  162.       xfree ((void *) di);
  163.       di = prdi;
  164.       /* here we have done redo of one index deletion. */
  165.       break; /* this function expect deletion of only one index - see (++) above */ 
  166.     }
  167. }
  168. /*
  169.  * redo "create index" operation.
  170.  *                                unclear logic ??? /mk
  171.  *
  172.  */
  173. void
  174. redo_cind (char *a, i2_t n, u2_t sn, u2_t pnr,
  175.            u2_t indr, struct des_tid *tid)
  176. {
  177.   struct ldesind *di;
  178.   char *tuple;
  179.   struct des_index desind;
  180.   struct d_r_t *desrel;
  181.   u2_t kn = 0, size = 0, indn, i, corsize;
  182.   i4_t ordrn;
  183.   struct des_tid ref_tid;
  184.   
  185.   ordrn = t4bunpack (a + scscal (a));
  186.   for (desrel = firstrel;  desrel != NULL; desrel = desrel->drlist)
  187.     if (desrel->desrbd.relnum == ordrn)
  188.       break;
  189.   if (desrel == NULL)
  190.     {
  191.       struct id_rel idr;
  192.       idr.urn.segnum = sn;
  193.       idr.urn.obnum = ordrn;
  194.       idr.pagenum = pnr;
  195.       idr.index = indr;
  196.       desrel = crtfrd (&idr, a);
  197.     }
  198.   corsize = get_placement (sn, tid, &ref_tid);
  199.   a += corsize;
  200.   tuple = a;
  201.   a = INDEX_PTR(tuple,desrel);
  202.   indn = desrel->desrbd.indnum + 1; /* we expect creation of only one index */
  203.   assert( indn >0);
  204.   for (i = 0; i < indn; i++)
  205.     {
  206.       BUFUPACK(a,desind);
  207.       kn = desind.kifn & ~UNIQ & MSK21B;
  208.       size = kn * size2b;
  209.       for (di = desrel->pid; di != NULL; di = di->listind)
  210. if (desind.unindex == di->ldi.unindex)
  211.           break;
  212.         else
  213.           a += size;  /* ???/mk */
  214.     }
  215.   if ((kn % 2) != 0)
  216.     size += size2b;
  217.   di = (struct ldesind *) xmalloc (size + ldisize + rfsize);
  218.   bcopy (a, (char *) (di + 1), kn * size2b);
  219.   di->ldi = desind;
  220.   crtid (di, desrel);
  221.   crindci (di);
  222.   desrel->desrbd.indnum++;
  223.   n -= corsize;
  224.   ordmod (sn, RDRNUM, tid, &ref_tid, corsize, tuple, n);
  225.   fill_ind (desrel, di);
  226. }
  227. u2_t
  228. get_placement (u2_t sn, struct des_tid *tid, struct des_tid *ref_tid)
  229. {
  230.   char *a, *asp = NULL;
  231.   u2_t *afi, *ai, corsize;
  232.   struct A pg;
  233.   unsigned char t;
  234.   while ((asp = getpg (&pg, sn, tid->tpn, 's')) == NULL);
  235.   afi = (u2_t *) (asp + phsize);
  236.   ai = afi + tid->tindex;
  237.   a = asp + *ai;
  238.   t = *a & MSKCORT;
  239.   if (t == IND)
  240.     { /* indirect reference */
  241.       u2_t pn2, ind2;
  242.       ind2 = t2bunpack (a + 1);
  243.       pn2 = t2bunpack (a + 1 + size2b);
  244.       putpg (&pg, 'n');
  245.       while ((asp = getpg (&pg, sn, pn2, 's')) == NULL);
  246.       afi = (u2_t *) (asp + phsize);
  247.       ai = afi + ind2;
  248.       assert (*ai != 0);
  249.       ref_tid->tpn = pn2;
  250.       ref_tid->tindex = ind2;
  251.     }
  252.   else
  253.     ref_tid->tpn = (u2_t) ~ 0;
  254.   corsize = calsc (afi, ai);
  255.   putpg (&pg, 'n');
  256.   return (corsize);
  257. }
  258. void
  259. delscd (u2_t n, char *a)
  260. {
  261.   char *s;
  262.   i4_t k;
  263.   for (k = 0; n != 0 && k < maxscan; k++)
  264.     for (; (s = *(scptab + k)) != NULL; k++)
  265.       if (a == ((struct d_mesc *) s)->pobsc)
  266. {
  267.   xfree ((void *) s);
  268.   n--;
  269. }
  270. }
  271. void
  272. fill_ind (struct d_r_t *desrel, struct ldesind *desind)
  273. {
  274.   char *c = NULL, *cort;
  275.   u2_t *ai, *afi, *ali, ind;
  276.   struct A inpg;
  277.   struct d_sc_i *scind;
  278.   struct ldesscan *disc;
  279.   u2_t sn, pn, size, fdf;
  280.   i2_t num;
  281.   i4_t rep;
  282.   struct des_tid tid;
  283.   struct ldesind *di, *prevdi;
  284.   char mas[BD_PAGESIZE];
  285.   sn = desrel->segnr;
  286.   fdf = desrel->desrbd.fdfnum;
  287.   scind = rel_scan (sn, desrel->desrbd.relnum, (char *) desrel, &num, 0, NULL, NULL, 0, 0, NULL);
  288.   disc = &scind->dessc;
  289.   rep = fgetnext (disc, &pn, &size, FASTSCAN);
  290.   for (; rep != EOI;)
  291.     {
  292.       while ((c = getpg (&inpg, sn, pn, 's')) == NULL);
  293.       afi = (u2_t *) (c + phsize);
  294.       ali = afi + ((struct page_head *) c)->lastin;
  295.       tid.tpn = pn;
  296.       for (ai = afi, ind = 0; ai <= ali; ai++, ind++)
  297. if (*ai != 0 && CHECK_PG_ENTRY(ai))
  298.   {
  299.     tid.tindex = ind;
  300.     cort = c + *ai;
  301.     keyform (desind, fdf, mas, cort);
  302.     ordindi (desind, mas, &tid);
  303.   }
  304.       putpg (&inpg, 'n');
  305.       rep = getnext (disc, &pn, &size, FASTSCAN);
  306.     }
  307.   delscan (num);
  308.   if ((di = desrel->pid) == NULL)
  309.     desrel->pid = desind;
  310.   else
  311.     {
  312.       do
  313. {
  314.   prevdi = di;
  315.   di = di->listind;
  316. }  
  317.       while( di != NULL);
  318.       prevdi->listind = desind;
  319.     }
  320.   desind->listind = NULL;
  321. }
  322. struct d_r_t *
  323. crtfrd (struct id_rel *pidrel, char *tuple)
  324. {
  325.   struct d_r_t *desrel;
  326.   desrel = crtrd (pidrel, tuple);
  327.   if (desrel->desrbd.indnum != 0)
  328.     crt_all_id (desrel, tuple);
  329.   return (desrel);
  330. }
  331. void
  332. crt_all_id (struct d_r_t *desrel, char *a)
  333. {
  334.   u2_t i, indn, size;
  335.   u2_t kn1, size1;
  336.   struct des_index cdi;
  337.   struct ldesind *di;
  338.   a += scscal (a) + drbdsize + desrel->desrbd.fieldnum * rfsize;
  339.   indn = desrel->desrbd.indnum;
  340.   for (i = 0; i < indn; i++)
  341.     {
  342.       dindunpack (&cdi, a);
  343.       a += dinsize;
  344.       kn1 = cdi.kifn & ~UNIQ & MSK21B;
  345.       size = kn1 * size2b;
  346.       size1 = size;
  347.       if (kn1 % 2 != 0)
  348. size1 += size2b;
  349.       size1 += rfsize;
  350.       di = (struct ldesind *) xmalloc (ldisize + size1);
  351.       di->ldi = cdi;
  352.       bcopy (a, (char *) (di + 1), size);
  353.       a += size;
  354.       di->listind = desrel->pid;
  355.       desrel->pid = di;
  356.       crtid (di, desrel);
  357.     }
  358. }
  359. void
  360. dindunpack (struct des_index *di, char *pnt)
  361. {
  362. /*
  363.     di->unindex=t4bunpack(pnt); pnt+=size4b;
  364.     di->rootpn=t2bunpack(pnt); pnt+=size2b;
  365.     di->kifn=t2bunpack(pnt); pnt+=size2b;
  366.     */
  367.   bcopy (pnt, (char *) di, dinsize);
  368. }