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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  * insert.k  -   insert statements functionalization. 
  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 Andrew Yahin. 1994
  9.  * Rewritten by Michael Kimelman. 1995
  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: insert.k,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  29. #include "trl.h"
  30. #include "opt.h"
  31. #include <assert.h>
  32. #include "tassert.h"
  33. static void
  34. add_defaults(TXTREF tblptr,TXTREF into,TXTREF ins_list)
  35. {
  36.   TXTREF cc[3],prev[3];
  37.   i4_t    i;
  38.   
  39.   cc[0] = COR_COLUMNS(TABL_DESC(tblptr));
  40.   cc[1] = DOWN_TRN(into);
  41.   cc[2] = DOWN_TRN(ins_list);
  42.   for(i=0;i<3;i++) prev[i]=TNULL;
  43.   while(cc[0])
  44.     {
  45.       if ( cc[1]==TNULL || COL_NO(cc[0]) < COL_NO(OBJ_DESC(cc[1])) )
  46.         {
  47.   /* add default value for skipped column */
  48.   TXTREF newptr;
  49.   
  50.   /* add new colptr node in 'into' list */
  51.   newptr= #(ColPtr <cc[0]>) ;
  52.   RIGHT_TRN(newptr)=cc[1];
  53.   if(prev[1]) RIGHT_TRN(prev[1]) = newptr;
  54.   else        DOWN_TRN(into)     = newptr;
  55.   cc[1]=newptr;
  56.   ARITY_TRN(into) ++;
  57.   
  58.   /* add default value in values list */
  59.           if (COL_DEFAULT(cc[0])==TNULL)
  60.             {
  61.               lperror("Column '%s.%s.%s' has no default value and "
  62.                       "omitted in insert list",
  63.                       STRING(TBL_FNAME(COR_TBL(COL_TBL(cc[0])))),
  64.                       STRING(TBL_NAME(COR_TBL(COL_TBL(cc[0])))),
  65.                       STRING(COL_NAME(cc[0])));
  66.               newptr = #(Null_vl <COL_TYPE(cc[0])>) ;
  67.             }
  68.           else
  69.             newptr=copy_trn(COL_DEFAULT(cc[0]));
  70.   RIGHT_TRN(newptr)=cc[2];
  71.   if(prev[2]) RIGHT_TRN(prev[2]) = newptr;
  72.   else        DOWN_TRN(ins_list) = newptr;
  73.   cc[2]=newptr;
  74.   ARITY_TRN(ins_list) ++;
  75. }
  76.       adjust_parameter(cc[2],cc[1]); /* change param name and nullability */
  77.       for(i=0;i<3;i++)
  78.         {
  79.           prev[i]=cc[i];
  80.           cc[i] = RIGHT_TRN(cc[i]);
  81. }
  82.     }
  83. }
  84. TXTREF 
  85. process_insert(TXTREF insert_stmt)
  86. {
  87.   TXTREF tblptr,into,vals;
  88.   TXTREF ins_list;
  89.   enum token    code;
  90.   
  91.   TASSERT(CODE_TRN(insert_stmt) == INSERT, insert_stmt);
  92.   tblptr = DOWN_TRN(insert_stmt);
  93.   TASSERT(CODE_TRN(tblptr)==TBLPTR,insert_stmt);
  94.   /*
  95.    * at first let's check scan column list - 
  96.    * are there all table columns 
  97.    */
  98.   check_scan_cols(tblptr); /* uploading to scan all table columns... */
  99.   /*
  100.    * now there are all columns in scan and we can add default values in 
  101.    * insert list
  102.    */
  103.   into = RIGHT_TRN(tblptr);
  104.   code = CODE_TRN(into);
  105.   if( code != INTO)
  106.     {
  107.       TASSERT(code==QUERY || code==IVALUES,insert_stmt);
  108.       vals = into;
  109.       into = TNULL;
  110.       if(code==QUERY)
  111.         {
  112.           TXTREF selection = RIGHT_TRN(DOWN_TRN(vals));
  113.           TASSERT(CODE_TRN(selection) == SELECTION,insert_stmt);
  114.           ins_list = selection;
  115.         }
  116.       else
  117.         ins_list = vals;
  118.     }
  119.   else /* IF  code==INTO */
  120.     {
  121.       vals = RIGHT_TRN(into);
  122.       code = CODE_TRN(vals);
  123.       TASSERT(code==QUERY || code==IVALUES,insert_stmt);       
  124.       /* We have now the list of values to initialize given column list */
  125.       /* We have to complete this list by default values for all column, which 
  126.        * was absent in given list of columns 
  127.        */
  128.       /* sort 'into' and 'selection' list */
  129.       /* add additional nodes to into & selection lists */
  130.       if(code==QUERY)
  131.         {
  132.           TXTREF selection = RIGHT_TRN(DOWN_TRN(vals));
  133.           TASSERT(CODE_TRN(selection) == SELECTION,insert_stmt);
  134.           ins_list = selection;
  135.           sort_list_by_col_no(&(DOWN_TRN(into)),&(DOWN_TRN(selection)),NULL,0,
  136.                               "column and inserted value are of incompatible types",
  137.                               NULL);
  138.         }
  139.       else
  140.         {
  141.           ins_list = vals;
  142.           sort_list_by_col_no(&(DOWN_TRN(into)),&(DOWN_TRN(vals)),NULL,0,
  143.                               "column and inserted value are of incompatible types",
  144.                               NULL);
  145.         }
  146.       add_defaults(tblptr,into,ins_list);
  147.     }
  148.   /* We have now the list of values to initialize all column of the table */
  149.   /* Let's check if they are coherent */
  150.   sort_list_by_col_no(&(COR_COLUMNS(TABL_DESC(tblptr))),
  151.                       &(DOWN_TRN(ins_list)), NULL,1,
  152.                       "column and inserted value are of incompatible types",
  153.                       NULL);
  154.     
  155.   SCAN_PTR(insert_stmt) = TABL_DESC(tblptr);
  156.   free_node(tblptr);
  157.   if(into)
  158.     free_tree(into);
  159.   {
  160.     TXTREF v, tbl,scan;
  161.     scan = SCAN_PTR(insert_stmt);
  162.     tbl = COR_TBL(scan);
  163.     for ( v= LOCAL_VCB_ROOT; v; v = RIGHT_TRN(v))
  164.       if ( (v!= scan) && (CODE_TRN(v) == SCAN) && (COR_TBL(v) == tbl))
  165.         break;
  166.     if (v)
  167.       vals = #(TblPtr <make_scan(DOWN_TRN(RIGHT_TRN(DOWN_TRN(vals))),vals)> ) ;
  168.   }
  169.   DOWN_TRN(insert_stmt)  = vals;
  170.   ARITY_TRN(insert_stmt) = 1;
  171.   return insert_stmt;
  172. }