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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  * update.k  -    convert update statements tree to functional oriented
  3.  *                form. 
  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 Andrew Yahin, 1995.
  10.  * Rewritten by Michael Kimelman. 1996
  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: update.k,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  30. #include "tree_gen.h"
  31. #include "opt.h"
  32. #include "tassert.h"
  33. #include <assert.h>
  34. /*===========================================================
  35.   These routines transform update trees to universal form:
  36.  1. Positioned update
  37.     (Update <cursor_scan_ptr> [] {
  38.       (TblPtr (Scan (Table "..." "update_on_this_table")))
  39.       (AssList {
  40.         (Assign { (ColPtr (Scolumn 0 ...)) (expr0) })            . . .
  41.         (Assign { (ColPtr (Scolumn 3 ...)) (expr3) })
  42.       } )
  43.     } )
  44.       
  45.  ==>>
  46.     (Update <cursor_scan_ptr> [ 0 ... 3 ] {
  47.       (Query {
  48.         (From (TblPtr ..on_this_table..))
  49.         (Selection {
  50.           (expr0)
  51.           . . .
  52.           (expr3)
  53.         } )
  54.     } )
  55. -----------------------------------------------------------
  56.  2. Searced update
  57.     (Update <0> [] {
  58.       (TblPtr (Scan (Table "..." "update_on_this_table")))
  59.       (AssList {
  60.         (Assign { (ColPtr .c0.) (expr0) })
  61.              . . .
  62.         (Assign { (ColPtr .c3.) (expr3) })
  63.       } )
  64.       ? (Where {...})
  65.     } )
  66.  ==>>
  67.     (Insert <update_on_this_table> {
  68.       (TblPtr (Scan (TmpTable 
  69.         (Delete
  70.           (Query {
  71.             (From (TblPtr ....))
  72.             (Selection {
  73.               (ColPtr .0.)
  74.               (expra0)
  75.                . . .
  76.                (expra3)
  77.                (ColPtr .n.)
  78.             } )
  79.             (Where {...}) ;; optional
  80.           } )
  81.         )
  82.       )))
  83.     } )
  84.     
  85. ===========================================================*/
  86. /*
  87.  * 'update_list' creates array of number of updated columns and list
  88.  *  of expressions to modify them.
  89.  */
  90. static TXTREF
  91. update_list(TXTREF upd)
  92. {
  93.   TXTREF list=TNULL,arr,assign,set_list;
  94.   i4_t i;
  95.   set_list = RIGHT_TRN(DOWN_TRN(upd));
  96.   TASSERT(CODE_TRN(set_list)==ASSLIST,upd);
  97.   arr=gen_vect(ARITY_TRN(set_list));
  98.   assign=DOWN_TRN(set_list);
  99.   for(i=0;assign;i++)
  100.     {
  101.       TXTREF cn, colptr;
  102.       cn = assign;
  103.       assign = RIGHT_TRN(assign);
  104.       TASSERT(CODE_TRN(cn)==ASSIGN,cn);
  105.       colptr   = DOWN_TRN(cn);
  106.       free_node(cn);
  107.       TASSERT(CODE_TRN(colptr)==COLPTR,colptr);
  108.       VOP(arr,i).l = COL_NO(OBJ_DESC(colptr));
  109.       list   = join_list(list,RIGHT_TRN(colptr));
  110.       adjust_parameter(RIGHT_TRN(colptr),colptr); /* change param name and nullability */
  111.       free_node(colptr);
  112.     }
  113.   free_node(set_list);
  114.   UPD_CLMNS(upd)=arr;
  115.   return list;
  116. }
  117. static TXTREF
  118. extend_update(TXTREF updlist,TXTREF upvec, TXTREF scan)
  119. {
  120.   TXTREF newlist, scol, csel, *ue ;
  121.   i4_t    ue_len, i,l;
  122.   l = VLEN(upvec);
  123.   ue_len = TBL_NCOLS(COR_TBL(scan));
  124.   ue = (TXTREF*) xmalloc(ue_len * sizeof(TXTREF));
  125.   for( i = 0, csel = updlist; csel; i++, csel = RIGHT_TRN(csel))
  126.     {
  127.       assert ( i < l);
  128.       ue[VOP(upvec,i).l] = csel;
  129.     }
  130.   for (i=0,scol = COR_COLUMNS(scan);scol;scol = RIGHT_TRN(scol),i++)
  131.     if (ue[i]== TNULL)
  132.       {
  133.         TASSERT(COL_NO(scol)==i,scol);
  134.         ue[i] = #(ColPtr (C_code "scol"));
  135.       }      
  136.   for(i = 1; i < ue_len; i++)
  137.     RIGHT_TRN(ue[i-1]) = ue[i];
  138.   RIGHT_TRN(ue[ue_len-1]) = TNULL;
  139.   newlist = ue[0];
  140.   xfree(ue);
  141.   return newlist;
  142. }
  143. TXTREF
  144. process_update(TXTREF upd)
  145. {
  146.   TXTREF tblptr=DOWN_TRN(upd);
  147.   TXTREF where=RIGHT_TRN(RIGHT_TRN(tblptr));
  148.   TXTREF updlist=update_list(upd);
  149.   TASSERT(CODE_TRN(tblptr)==TBLPTR,upd);
  150.   if ( UPD_CURS(upd) )
  151.     {
  152.       DOWN_TRN(upd) =
  153. #       (Query
  154.          {
  155.            (From {(C_code "tblptr")})
  156.            (Selection {(C_code:list "updlist")})  
  157.            (C_code "where")
  158.          } ) ;
  159.       ARITY_TRN(upd) = 1;
  160.     }
  161.   else
  162.     {
  163.       /* special processing of update to avoid engine cycling and phantoms */
  164.       TXTREF scan, ss;
  165.       check_scan_cols(tblptr); /* uploading to scan all table columns... */
  166.       ss = TABL_DESC(tblptr);
  167.       scan = gen_node(SCAN);
  168.       COR_TBL(scan) = COR_TBL(ss);
  169.       add_info(scan);
  170.       TABL_DESC(tblptr) = scan ; /* a bit stupid action because of 'check_scan_cols' interface */
  171.       check_scan_cols(tblptr);   /* uploading to scan all table columns... */
  172.       TABL_DESC(tblptr) = ss;    /* recovering */
  173.       updlist = extend_update(updlist,UPD_CLMNS(upd),ss);
  174.       ss =
  175. #       (Delete {
  176.            (Query
  177.             {
  178.               (From {(C_code "tblptr")})
  179.               (Selection {(C_code:list "updlist")})  
  180.               (C_code "where")
  181.             } )
  182.         } ) ;
  183.       UPD_CLMNS (ss) = UPD_CLMNS (upd);
  184.       
  185.       CODE_TRN(upd) = INSERT;
  186.       SCAN_PTR(upd) = scan;
  187.       DOWN_TRN(upd) = #(TblPtr (C_code "make_scan(updlist,ss)"));
  188.       ARITY_TRN(upd) = 1;
  189.     }
  190.   return upd;
  191. }