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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  struct.c - special functions for dumping of internal commands to
  3.  *             module and some additional functions for synthesator
  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 Konstantin Dyshlevoj
  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: struct.c,v 1.247 1997/04/24 17:47:48 kml Exp $ */
  29.   
  30. #include "global.h"
  31. #include "syndef.h"
  32. #include "engine/fieldtp.h"
  33. #include "tassert.h"
  34. extern i4_t   *chconstr_col_use;
  35. extern i4_t    ch_col_use_num;
  36. extern SH_Info *tr_arr;
  37. extern i4_t tr_cnt, tr_max;
  38. #define ADD_CUR_PG(d) { CurPg += d; ALIGN(CurPg,SZ_LNG); }
  39. #define SET_ENUM(x) { *V_PTR(CurPg,enum CmdCode)=x; 
  40.                       ADD_CUR_PG (sizeof(enum CmdCode)); }
  41. /*
  42.  * 'set_command' puts the command to module for interpreter 
  43.  * returns VADR of the commad's structure     
  44.  */
  45. VADR
  46. set_command (enum CmdCode code, char *com_adr, i4_t com_size)
  47. {
  48.   VADR adr_res;
  49.   static i4_t min_rest_size = 3 * sizeof(i4_t) + SIZES (S_GoTo);
  50.   /* check for room for "Goto ; next_vm_piece " block at the end
  51.    * of currenly filled virtual memory portion.
  52.    */
  53.   
  54.   if (MaxPg - CurPg < min_rest_size + com_size)
  55.     {/* additional portion of virtual memory required */
  56.       VADR NewPg = VMALLOC (INTERP_MODULE_DELTA, char);
  57.       
  58.       SET_ENUM (GoTo);
  59.       Pr_GoTo (NewPg, CurPg);
  60.       ADD_CUR_PG (SIZES (S_GoTo));
  61.       SET_ENUM (next_vm_piece);
  62.       CurPg = NewPg;
  63.       ALIGN(CurPg,SZ_LNG);
  64.       MaxPg = CurPg + INTERP_MODULE_DELTA;
  65.     }      
  66.   SET_ENUM(code);
  67.   adr_res = CurPg;
  68.   if (com_adr)
  69.     {
  70.       bcopy (com_adr, V_PTR(CurPg,char), com_size);
  71.       ADD_CUR_PG (com_size);
  72.     }
  73.   return adr_res;
  74. } /* set_command */
  75. void
  76. Pr_Procedure (VADR Proc_Adr)
  77. /* insertion to module of command for colling *
  78.  * the procedure from address Proc_Adr        */
  79. {
  80.   struct S_Procedure D_Procedure;
  81.   
  82.   D_Procedure.ProcBeg = Proc_Adr;
  83.   
  84.   SET_CMD (Procedure);
  85. }
  86. void
  87. Pr_SCAN (VADR Tid, VADR Scan, char OperType, char mode,
  88.  i4_t nr, VADR rlist, i4_t nl, VADR list, i4_t ic,
  89.  VADR range, i4_t nm, VADR mlist, VADR Ex, VADR CmdPlace)
  90. {
  91.   struct S_OPSCAN D_OPSCAN;
  92.   /* table scan                            */
  93.   D_OPSCAN.Scan = Scan;
  94.   /* Tabid,Indid or Filid                  */
  95.   D_OPSCAN.Tid = Tid;
  96.   /* operation type of System of Memory    */
  97.   /* and  Synchronization Managment        */
  98.   D_OPSCAN.OperType = OperType;        
  99.   /* open mode                             */
  100.   D_OPSCAN.mode = mode;
  101.   /* the number of columns which values will be selected */
  102.   D_OPSCAN.nr = nr;
  103.   /* array of column numbers which values  */
  104.   /* will be selected                      */
  105.   D_OPSCAN.rlist = rlist;           
  106.   D_OPSCAN.nl = nl;
  107.   /* array of VADR for trees of SP         */
  108.   D_OPSCAN.list = list;
  109.   D_OPSCAN.ic = ic;
  110.   /* scan range - restricted form of       */
  111.   /* conditions for columns included in    */
  112.   /* idexes = idexes; array of VADR        */
  113.   D_OPSCAN.range = range;           
  114.   /* the number of columns which values    */
  115.   /* will be modified                      */
  116.   D_OPSCAN.nm = nm;
  117.   /* array of column number which values   */
  118.   /* will be modified                      */
  119.   D_OPSCAN.mlist = mlist;
  120.   /* exit in the case of                   */
  121.   /* incompatibility of  SP                */
  122.   D_OPSCAN.Exit = Ex;
  123.   if (CmdPlace)
  124.     PLACE_CMD (CmdPlace, OPSCAN);
  125.   else
  126.     SET_CMD (OPSCAN);
  127. }
  128. void
  129. Pr_SORTTBL (VADR TidIn, VADR TidOut, i4_t ns, VADR rlist, char fl, char order)
  130. {
  131.   struct S_SORTTBL D_SORTTBL;
  132.   D_SORTTBL.TidIn = TidIn;
  133.   D_SORTTBL.TidOut = TidOut;
  134.   D_SORTTBL.ns = ns; 
  135.   D_SORTTBL.rlist = rlist; 
  136.   D_SORTTBL.fl = fl; 
  137.   D_SORTTBL.order = order;
  138.   
  139.   SET_CMD (SORTTBL);
  140. }
  141. void
  142. Pr_MKUNION (VADR TidIn1, VADR TidIn2, VADR TidOut)
  143. {
  144.   struct S_MKUNION D_MKUNION;
  145.   D_MKUNION.TidIn1 = TidIn1;       
  146.   D_MKUNION.TidIn2 = TidIn2;       
  147.   D_MKUNION.TidOut = TidOut;
  148.   
  149.   SET_CMD (MKUNION);
  150. }
  151. void
  152. Pr_GROUP (VADR TidIn, VADR TidOut, i4_t ng, VADR glist,
  153.   char order, i4_t nf, VADR flist, VADR fl)
  154. {
  155.   struct S_MKGROUP D_MKGROUP;
  156.   D_MKGROUP.TidIn = TidIn;     
  157.   D_MKGROUP.TidOut = TidOut;    
  158.   D_MKGROUP.ng = ng;        
  159.   D_MKGROUP.glist = glist;     
  160.   D_MKGROUP.order = order;     
  161.   D_MKGROUP.nf = nf;        
  162.   D_MKGROUP.flist = flist;     
  163.   D_MKGROUP.fl = fl;        
  164.       
  165.   SET_CMD (MKGROUP);
  166. }
  167. void
  168. Pr_FUNC (VADR Tid, char OperType, i4_t nl, VADR list, i4_t ic, VADR range,
  169.  VADR colval, i4_t nf, VADR flist, VADR fl, VADR Exit, VCBREF FirClm)
  170. {
  171.   VADR cmd;
  172.   struct S_FUNC D_FUNC;
  173.   
  174.   D_FUNC.flag = 'n';
  175.   D_FUNC.Tid.off = Tid;      
  176.   D_FUNC.OperType = OperType;
  177.   D_FUNC.nl = nl;      
  178.   D_FUNC.list.off = list;    
  179.   D_FUNC.ic = ic;      
  180.   D_FUNC.range.off = range;   
  181.   D_FUNC.colval.off = colval;  
  182.   D_FUNC.nf = nf;      
  183.   D_FUNC.flist.off = flist;   
  184.   D_FUNC.fl.off = fl;       
  185.   D_FUNC.Exit.off = Exit;     
  186.                       
  187.   STEP_CMD  (cmd, FUNC);
  188.   PLACE_CMD (cmd, FUNC);
  189.   
  190.   if (!Exit)
  191.     {
  192.       assert (!FuncExit);
  193.       /* address of command "ERROR" in section must be saved in field Exit */
  194.       FuncExit = &(V_PTR(cmd, struct S_FUNC)->Exit.off);
  195.     }
  196. }
  197. void
  198. Pr_FINDROW (VADR Scan, i4_t nr, VADR ColPtr, VADR Exit, VADR CmdPlace)
  199. {
  200.   struct S_FINDROW  D_FINDROW;
  201.   D_FINDROW.flag = 'n';
  202.   D_FINDROW.Scan.off = Scan;    
  203.   D_FINDROW.nr = nr;      
  204.   D_FINDROW.ColPtr.off = ColPtr;  
  205.   D_FINDROW.Exit.off = Exit;
  206.   
  207.   if (CmdPlace)
  208.     PLACE_CMD (CmdPlace, FINDROW);
  209.   else
  210.     SET_CMD (FINDROW);
  211. } /* PrFINDROW */
  212. void
  213. Pr_READROW (VADR Scan, i4_t nr, VADR ColPtr, VADR rlist)
  214. {
  215.   struct S_READROW D_READROW;
  216.   
  217.   D_READROW.flag = 'n';        
  218.   D_READROW.Scan.off = Scan;      
  219.   D_READROW.nr = nr;        
  220.   D_READROW.ColPtr.off = ColPtr;    
  221.   D_READROW.rlist.off = rlist;     
  222.                          
  223.   SET_CMD (READROW);
  224. } /* PrREADROW */
  225. void
  226. Pr_UNTIL (VADR cond, VADR ret, VADR CmdPlace)
  227. {
  228.   struct S_until D_until;
  229.   
  230.   D_until.flag     = 'n';
  231.   D_until.cond.off = cond;
  232.   D_until.ret.off  = ret;
  233.   if (CmdPlace)
  234.     PLACE_CMD (CmdPlace, until);
  235.   else
  236.     SET_CMD (until);
  237. }
  238. void
  239. Pr_COND_EXIT (TXTREF Tree)
  240. {
  241.   MASK Depend;
  242.   struct S_COND_EXIT D_COND_EXIT;
  243.   
  244.   D_COND_EXIT.flag = 'n';
  245.   D_COND_EXIT.Tree.off = VNULL;
  246.   SET (tr, D_COND_EXIT.Tree.off = 
  247.        Tr_RecLoad (Tree, &Depend, FALSE, NULL), Depend);
  248.  
  249.   SET_CMD (COND_EXIT);
  250. }
  251. void
  252. Pr_GoTo (VADR Br, VADR CmdPlace)
  253. {
  254.   struct S_GoTo D_GoTo;
  255.   D_GoTo.flag = 'n';
  256.   D_GoTo.Branch.off = Br;
  257.   if (CmdPlace)
  258.     PLACE_CMD (CmdPlace, GoTo);
  259.   else
  260.     SET_CMD (GoTo);
  261. }
  262. VADR
  263. SelArr (TXTREF SelNode, i4_t *Num)
  264. /* results VADR of array of pointers (PSECT_PTR) to trees *
  265.  * from SELECT & number of elements in this array to Num. */
  266. {
  267.   VADR PSect;
  268.   i4_t i;
  269.   TXTREF ColNode;
  270.   MASK Depend;
  271.   *Num = 0;
  272.   ColNode = DOWN_TRN (SelNode);
  273.   while (ColNode)
  274.     {
  275.       ColNode = COL_NEXT (ColNode);
  276.       (*Num)++;
  277.     }
  278.   PSect = VMALLOC (*Num, PSECT_PTR);
  279.   ColNode = DOWN_TRN (SelNode);
  280.   for (i = 0; i < *Num; i++)
  281.     {
  282.       SET (tr, V_PTR (PSect, PSECT_PTR)[i].off =
  283.    Tr_RecLoad (ColNode, &Depend, FALSE, NULL), Depend);
  284.       ColNode = COL_NEXT (ColNode);
  285.     }
  286.   return PSect;
  287. }
  288. void
  289. Pr_RetPar (VADR OutList, i4_t OutNum, char ExitFlag)
  290. {
  291.   struct S_RetPar D_RetPar;
  292.   
  293.   D_RetPar.flag = 'n';
  294.   D_RetPar.ExitFlag = ExitFlag;
  295.   D_RetPar.OutNum = OutNum;  
  296.   D_RetPar.OutList.off = OutList; 
  297.   SET_CMD (RetPar);
  298. }
  299. void
  300. Pr_INSROW (VADR Tbid, i4_t nv, VADR InsList, VCBREF FirClm,
  301.    VCBREF RealScan, i4_t nm, VADR V_mlist, VADR Scan)
  302. {
  303.   VADR V_Tp;
  304.   sql_type_t *Tp;
  305.   VCBREF CurClm;
  306.   i4_t *mlist = NULL;
  307.   struct S_INSROW D_INSROW;
  308.   D_INSROW.flag = 'n';
  309.   D_INSROW.Tid.off = Tbid;      
  310.   D_INSROW.nv = nv;       
  311.   D_INSROW.InsList.off = InsList;  
  312.   D_INSROW.ClmTp.off = VNULL;    
  313.   D_INSROW.Constr.off = VNULL;
  314.   
  315.   P_VMALLOC (Tp, nv, sql_type_t );
  316.   for (CurClm = FirClm; CurClm; CurClm = COL_NEXT (CurClm))
  317.     Tp [COL_NO (CurClm)] = COL_TYPE (CurClm);
  318.   D_INSROW.ClmTp.off = V_Tp;
  319.   if (RealScan)
  320.     {
  321.       if (nm)
  322.         {
  323.           mlist = TYP_ALLOC (nm, i4_t);
  324.       
  325.           TYP_COPY (V_PTR (V_mlist, i4_t), mlist, nm, i4_t);
  326.         }
  327.       D_INSROW.Constr.off =
  328. Pr_Constraints (RealScan, Scan, (nm) ? UPDATE : INSERT, nm, mlist);
  329.       if (mlist)
  330.         xfree (mlist);
  331.     }
  332.   else
  333.     /* insertion into temporary table */
  334.     {
  335.       S_ConstrHeader *header;
  336.       VADR V_header;
  337.       
  338.       P_VMALLOC (header, 1, S_ConstrHeader);
  339.       header->tab_col_num = nv;
  340.       D_INSROW.Constr.off = V_header;
  341.     }
  342.   SET_CMD (INSROW);
  343. }
  344. void
  345. Pr_INSLIST (VADR Tbid, i4_t nv, VADR type_arr, VADR len,
  346.     VADR col_ptr, VADR credate, VADR cretime)
  347. {
  348.   struct S_INSLIST D_INSLIST;
  349.   D_INSLIST.flag = 'n';
  350.   D_INSLIST.Tid.off = Tbid;         
  351.   D_INSLIST.nv = nv;          
  352.   D_INSLIST.len.off = len;         
  353.   D_INSLIST.col_types.off = type_arr;
  354.   D_INSLIST.col_ptr.off = col_ptr;     
  355.   D_INSLIST.credat_adr.off = credate;  
  356.   D_INSLIST.cretime_adr.off = cretime; 
  357.      
  358.   SET_CMD (INSLIST);
  359. }
  360. void
  361. Pr_INSTAB (VADR TidFrom, VADR TidTo)
  362. {
  363.   struct S_INSTAB D_INSTAB;
  364.   D_INSTAB.TidFrom = TidFrom;          
  365.   D_INSTAB.TidTo = TidTo;
  366.   
  367.   SET_CMD (INSTAB);
  368. }
  369. void
  370. Pr_UPDATE (VADR Scan, i4_t nm, VADR OutList, VCBREF ScanNode, VADR V_mlist)
  371. {
  372.   VADR V_Tp = VNULL;
  373.   sql_type_t *Tp = NULL;
  374.   VCBREF CurClm, FirTabClm;
  375.   i4_t i, *mlist = NULL;
  376.   struct S_MODROW D_MODROW;
  377.     
  378.   D_MODROW.flag = 'n';
  379.   D_MODROW.Scan.off = Scan;    
  380.   D_MODROW.nl = nm;     
  381.   D_MODROW.mlist.off = V_mlist;  
  382.   D_MODROW.OutList.off = OutList; 
  383.   D_MODROW.ClmTp.off = VNULL;
  384.   D_MODROW.Constr.off = VNULL;
  385.   
  386.   if (nm)
  387.     {
  388.       mlist = TYP_ALLOC (nm, i4_t);
  389.       TYP_COPY (V_PTR (V_mlist, i4_t), mlist, nm, i4_t);
  390.       P_VMALLOC (Tp, nm, sql_type_t );
  391.     }
  392.   FirTabClm = TBL_COLS (COR_TBL (ScanNode));
  393.   for (i = 0; i < nm; i++)
  394.     {
  395.       for (CurClm = FirTabClm; CurClm; CurClm = COL_NEXT (CurClm))
  396. if (COL_NO (CurClm) == mlist[i])
  397.   {
  398.     Tp [i] = COL_TYPE (CurClm);
  399.     break;
  400.   }
  401.       if (!CurClm)
  402. yyfatal ("Synthes: UPDATE: There is not information about type of column ");
  403.     }
  404.   
  405.   D_MODROW.ClmTp.off = V_Tp;
  406.   D_MODROW.Constr.off = Pr_Constraints (ScanNode, Scan, UPDATE, nm, mlist);
  407.   if (mlist)
  408.     xfree (mlist);
  409.   
  410.   SET_CMD (MODROW);
  411. }
  412. void
  413. Pr_DELETE (VADR Scan, VCBREF ScanNode)
  414. {
  415.   struct S_DELROW D_DELROW;
  416.   D_DELROW.Scan = Scan;
  417.   D_DELROW.Constr = Pr_Constraints (ScanNode, Scan, DELETE, 0, NULL);
  418.   
  419.   SET_CMD (DELROW);
  420. }
  421. void
  422. Pr_CLOSE (VADR Scan)
  423. {
  424.   struct S_CLOSE D_CLOSE;
  425.   
  426.   D_CLOSE.Scan = Scan;
  427.   SET_CMD (CLOSE);
  428. }
  429. void
  430. Pr_DROP (i4_t untabid)
  431. {
  432.   struct S_DROPBASE D_DROPBASE;
  433.   D_DROPBASE.untabid=untabid;
  434.   SET_CMD (DROPBASE);
  435. }
  436. void
  437. Pr_DROPTTAB (VADR Tbid)
  438. {
  439.   struct S_DROPTTAB D_DROPTTAB;
  440.   
  441.   D_DROPTTAB.Tid = Tbid;
  442.   
  443.   SET_CMD (DROPTTAB);
  444. }
  445. void
  446. Pr_ERROR (i4_t cod)
  447. {
  448.   struct S_ERROR D_ERROR;
  449.   
  450.   D_ERROR.Err = cod;
  451.   
  452.   SET_CMD (ERROR);
  453. }
  454. void
  455. Pr_CRETAB (VADR tabname, VADR owner, Segid segid, i4_t colnum,
  456.    i4_t nncolnum, VCBREF FirClm, VADR tabid)
  457. {
  458.   i4_t i;
  459.   sql_type_t *arr;
  460.   VADR V_arr;
  461.   VCBREF CurClm = FirClm;
  462.   
  463.   struct S_CRETAB D_CRETAB;
  464.   D_CRETAB.tabname = tabname;         
  465.   D_CRETAB.owner = owner;           
  466.   D_CRETAB.segid = segid;          
  467.   D_CRETAB.colnum = colnum;          
  468.   D_CRETAB.nncolnum = nncolnum;        
  469.   D_CRETAB.coldescr = VNULL;        
  470.   D_CRETAB.tabid = tabid;           
  471.   P_VMALLOC (arr, colnum, sql_type_t );
  472.   for (i = 0; CurClm; i++, CurClm = COL_NEXT (CurClm))
  473.     type_to_bd( &COL_TYPE (CurClm), arr + i);
  474.   D_CRETAB.coldescr = V_arr;
  475.   
  476.   SET_CMD (CRETAB);
  477. }
  478. void
  479. Pr_CREIND (VADR tabid, VADR indid, char uniq_fl, i4_t colnum, VADR clmlist)
  480. {
  481.   struct S_CREIND D_CREIND;
  482.   D_CREIND.tabid = tabid;           
  483.   D_CREIND.indid = indid;           
  484.   D_CREIND.uniq_fl = uniq_fl;         
  485.   D_CREIND.colnum = colnum;          
  486.   D_CREIND.clmlist = clmlist;
  487.   
  488.   SET_CMD (CREIND);
  489. }
  490. void
  491. Pr_PRIVLG (VADR untabid, VADR owner, VADR user, VADR privcodes, 
  492.    i4_t un, VADR ulist, i4_t rn, VADR rlist)
  493. {
  494.   struct S_PRIVLG D_PRIVLG;
  495.   D_PRIVLG.untabid = untabid;            
  496.   D_PRIVLG.owner = owner;               
  497.   D_PRIVLG.user = user;               
  498.    
  499.   D_PRIVLG.privcodes = privcodes;          
  500.   D_PRIVLG.un = un;                 
  501.   D_PRIVLG.ulist = ulist;              
  502.   D_PRIVLG.rn = rn;                 
  503.   D_PRIVLG.rlist = rlist;
  504.   
  505.   SET_CMD (PRIVLG);
  506. }
  507. void
  508. Pr_SavePar (VCBREF Dict)
  509. /* Dict - the beginning of operator vocabulary */
  510. {
  511.   VCBREF CurPar = Dict;
  512.   VADR PlaceOff;
  513.   i4_t n = 0, Num = 0;
  514.   struct S_SavePar D_SavePar;
  515.   D_SavePar.flag = 'n';
  516.       
  517.   for(CurPar = Dict, Num = 0; CurPar ; CurPar = RIGHT_TRN (CurPar))
  518.     if ((CODE_TRN (CurPar) == PARAMETER) &&
  519.         !TstF_TRN (CurPar,INDICATOR_F) &&
  520.         !TstF_TRN (CurPar, OUT_F))
  521.       Num++;
  522.   if (Num)
  523.     {
  524.       PlaceOff = VMALLOC (Num, PSECT_PTR);
  525.       for( CurPar = Dict, n = 0; CurPar; CurPar = RIGHT_TRN (CurPar))
  526.         if ((CODE_TRN (CurPar) == PARAMETER) &&
  527.             !TstF_TRN (CurPar,INDICATOR_F) &&
  528.             !TstF_TRN (CurPar, OUT_F))
  529.           V_PTR (PlaceOff, PSECT_PTR)[n++].off =
  530.             PAR_ADR (CurPar)                   =
  531.             prepare_HOLE (PAR_TTYPE (CurPar));
  532.       
  533.       D_SavePar.ParamNum = Num;
  534.       D_SavePar.PlaceOff.off = PlaceOff;
  535.       
  536.       SET_CMD (SavePar);
  537.     }
  538. } /* PrSavePar */
  539. void
  540. Pr_TMPCRE (VADR Tbid, VCBREF FirClm, i4_t nnulnum)
  541. {
  542.   sql_type_t *arr;
  543.   VADR V_arr;
  544.   VCBREF CurClm;
  545.   i4_t i, ColNum = 0;
  546.   struct S_TMPCRE D_TMPCRE;
  547.    
  548.   CurClm = FirClm;
  549.   while (CurClm)
  550.     {
  551.       ColNum++;
  552.       CurClm = COL_NEXT (CurClm);
  553.     }
  554.   P_VMALLOC (arr, ColNum, sql_type_t );
  555.   
  556.   for (i = 0, CurClm = FirClm; CurClm; i++, CurClm = COL_NEXT (CurClm))
  557.     type_to_bd (&COL_TYPE (CurClm), arr + COL_NO (CurClm));
  558.   
  559.   D_TMPCRE.Tid = Tbid;
  560.   D_TMPCRE.colnum = ColNum;
  561.   D_TMPCRE.nnulnum = nnulnum;
  562.   D_TMPCRE.coldescr = V_arr;
  563.   
  564.   SET_CMD (TMPCRE);
  565. } /* PrTMPCRE */
  566. #define Mk_InitDt(d, t)  P_VMALLOC (InitDt, 1, PrepSQ); 
  567.                          d = &(InitDt->ToDtStack.dat);  
  568.                          t = &(InitDt->ToDtStack.type)
  569. #define Mk_dat_typ       NL_FL(dat) = REGULAR_VALUE;    
  570.                          typ->code = T_BOOL;            
  571.                          typ->len = 0
  572. #define Mk_Call(x, prep) x->code    = CALLPR;           
  573.                          x->Dn.off  = V_InitDt;         
  574.                          x->Ptr.off = (prep) ?          
  575.     prepare_HOLE (*typ) : VNULL;
  576.                          x->Depend  = *Dep;             
  577.                          x->Handle  = 1;                
  578.                          x->Arity   = 0;                
  579.                          x->Ty = *typ
  580.  
  581. #define USE_HOLE     TRUE
  582. #define NOT_USE_HOLE FALSE
  583.  
  584. /* Next 3 functions form the tree in Query for SubQuery *
  585.  * in Exists | comrapision | quantified predicate.      *
  586.  * It return addr. of this tree (>0) or error (<0).     *
  587.  * Nod - node for subquery in compilator's tree,        *
  588.  * PTN - node formed in Tr_RecLoad.                     */
  589.  
  590. VADR
  591. SQ_Exists (TXTREF Nod, VADR V_PTN, MASK *Dep, float *sq_cost)
  592. {
  593.   VADR V_InitDt, V_res;
  594.   PrepSQ *InitDt;
  595.   TpSet  *dat;
  596.   sql_type_t   *typ;
  597.    
  598.   Mk_InitDt (dat, typ);
  599.   Mk_dat_typ;
  600.   InitDt->GoUpNeed = 0;
  601.   LNG_VL(dat) = FALSE;
  602.   
  603.   if ((V_res = ProcHandle (Nod, VNULL, TNULL, 0, Dep, sq_cost, NULL)) < 0)
  604.     return V_res;
  605.   V_PTR (V_InitDt, PrepSQ)->ProcAdr = V_res;
  606.   
  607.   Mk_Call (V_PTR (V_PTN, TRNode), USE_HOLE);
  608.   
  609.   return V_PTN;
  610. } /* SQ_Exists */
  611. VADR
  612. SQ_Quant (TXTREF Nod, VADR V_PTN, MASK *Dep, float *sq_cost)
  613. {
  614.   enum token code = CODE_TRN (Nod);
  615.   VADR V_InitDt, V_res, V_hole;
  616.   PrepSQ *InitDt;
  617.   TRNode *TRN_Comp;
  618.   TXTREF CompOp = DOWN_TRN (Nod);
  619.   TXTREF LeftOperand = DOWN_TRN (CompOp);
  620.   TXTREF SQTree = RIGHT_TRN (LeftOperand);
  621.   i4_t save_fl = Is_Operation (LeftOperand);
  622.   VADR Result;
  623.   TpSet  *dat;
  624.   sql_type_t   *typ;
  625.   MASK Depend = 0;
  626.   
  627.   Mk_InitDt (dat, typ);
  628.   Mk_dat_typ;
  629.   InitDt->GoUpNeed = 1;
  630.   LNG_VL(dat) = (code == ALL);
  631.   
  632.   /* Tree for SubQuery making : */
  633.   RIGHT_TRN (LeftOperand) = TNULL;
  634.   
  635.   if (save_fl)
  636.     { /* it's needed to save the result of left operand */
  637.       TXTREF Q_Noop = gen_node (NOOP);
  638.       
  639.       RIGHT_TRN (Q_Noop) = TNULL;
  640.       DOWN_TRN (Q_Noop)  = LeftOperand;
  641.       ARITY_TRN (Q_Noop)  = 1;
  642.       DOWN_TRN (CompOp) = Q_Noop;
  643.       Result = Tr_RecLoad (CompOp, &Depend, 0, NULL);
  644.   
  645. #define TRN_Noop  V_PTR (V_PTR (Result, TRNode)->Dn.off, TRNode)
  646. #define TRN_Left  V_PTR (TRN_Noop->Dn.off, TRNode)
  647.       
  648.       TRN_Noop->Rh.off = V_PTN;
  649.       TRN_Noop->Ty = TRN_Left->Ty;
  650.       RIGHT_TRN (Q_Noop) = SQTree;
  651.       OPRN_TYPE (Q_Noop) = TRN_Left->Ty;
  652.     
  653.       /* making tree TRN_Left as common tree of Query & SubQuery */
  654.       if (!(TRN_Left->Ptr.off))
  655. TRN_Left->Ptr.off = prepare_HOLE (TRN_Left->Ty);
  656.       SET (tr, TRN_Noop->Dn.off, Depend);
  657.       TRN_Left->Handle = TRN_Left->Depend;
  658.       TRN_Left->Depend = 0;
  659.       VAL_HOLE (LeftOperand) = TRN_Noop->Dn.off;
  660.       
  661. #undef TRN_Noop
  662. #undef TRN_Left
  663.     }
  664.   else
  665.     {
  666.       Result = Tr_RecLoad (CompOp, &Depend, 0, NULL);
  667.   
  668.       V_PTR (V_PTR (Result, TRNode)->Dn.off, TRNode)->Rh.off = V_PTN;
  669.       RIGHT_TRN (LeftOperand) = SQTree;
  670.     }
  671.   
  672.   V_hole = prepare_HOLE (V_PTR (Result, TRNode)->Ty);
  673.   TRN_Comp = V_PTR (Result, TRNode);
  674.   TRN_Comp->Ty.code = T_BOOL;
  675.   TRN_Comp->Ty.len =  0;
  676.   TRN_Comp->Ptr.off = V_hole;
  677.   
  678.   if ((V_res = ProcHandle (Nod, VNULL, TNULL, 0, Dep, sq_cost, NULL)) < 0)
  679.     return V_res;
  680.   V_PTR (V_InitDt, PrepSQ)->ProcAdr = V_res;
  681.   
  682.   Mk_Call (V_PTR (V_PTN, TRNode), NOT_USE_HOLE);
  683.   *Dep = V_PTR (Result, TRNode)->Depend = BitOR (Depend, *Dep);
  684.   
  685.   return Result;
  686. } /* SQ_Quant */
  687. VADR
  688. SQ_Comp (TXTREF Nod, VADR V_PTN, MASK *Dep, float *sq_cost)
  689.      /* Nod - SUBQUERY */
  690. {
  691.   VADR V_InitDt, V_res;
  692.   PrepSQ *InitDt;
  693.   TpSet  *dat;
  694.   sql_type_t   *typ;
  695.   
  696.   Mk_InitDt (dat, typ);
  697.   InitDt->GoUpNeed = 0;
  698.   NL_FL(dat) = UNKNOWN_VALUE;
  699.   V_PTR (V_PTN, TRNode)->Ty = *typ = OPRN_TYPE (Nod);
  700.   
  701.   if ((V_res = ProcHandle (Nod, VNULL, TNULL, 0, Dep, sq_cost, NULL)) < 0)
  702.     return V_res;
  703.   V_PTR (V_InitDt, PrepSQ)->ProcAdr = V_res;
  704.   
  705.   Mk_Call (V_PTR (V_PTN, TRNode), USE_HOLE);
  706.   
  707.   return V_PTN;
  708. } /* SQ_Comp */
  709. #undef Mk_InitDt
  710. #undef Mk_dat_typ
  711. #undef Mk_Call
  712. VADR
  713. Tr_RecLoad (TXTREF Nod, MASK * Depend, i4_t RhNeed, float *sq_cost)
  714. /* Recursive tree loading : to Depend is putted         *
  715.  * common dependence MASK of this tree (& all trees     *
  716.  * that are right from current if RhNeed == 1)          *
  717.  * RhNeed = 1 if there is needed to handle right        *
  718.  * reference of tree's header.                          *
  719.  * If sq_cost != NULL & Nod - SubQuery => the estimated *
  720.  * cost of this SubQuery is putted to sq_cost           */
  721. {
  722.   VCBREF obj;
  723.   TRNode *PTN;
  724.   VADR V_PTN, res, V_Rh, V_Dn;
  725.   MASK DnDepend = 0, RhDepend = 0;
  726.   
  727.   if (PRCD_DEBUG)
  728.     printf ("Struct:i4_t TrRecLoad()n");
  729.   
  730.   *Depend = 0;
  731.   
  732.   if (!Nod)
  733.     return VNULL;
  734.   
  735.   P_VMALLOC (PTN, 1, TRNode);
  736.   switch (CODE_TRN (Nod))
  737.     {
  738.     case COLPTR:
  739.       obj = OBJ_DESC (Nod);
  740.       PTN->code = CODE_TRN (obj);
  741.       PTN->Ty = COL_TYPE (obj);
  742.       if (PTN->code == SCOLUMN && !chconstr_col_use)
  743. {
  744.   *Depend = COR_MASK (COL_TBL (obj));
  745.   PTN->Ptr.off = COL_ADR (obj);
  746. }
  747.       else
  748. {
  749.           i4_t colno = COL_NO (obj);
  750.           
  751.   TASSERT (PTN->code == COLUMN || chconstr_col_use, Nod);
  752.   *Depend = 0;
  753.   PTN->Ptr.off = colno;
  754.   if (!chconstr_col_use [colno])
  755.     {
  756.       chconstr_col_use [colno] ++;
  757.       ch_col_use_num ++;
  758.     }
  759. }
  760.       break;
  761.     case PARMPTR:
  762.       PTN->code = PARAMETER;
  763.       obj = OBJ_DESC (Nod);
  764.       PTN->Ty = PAR_TTYPE (obj);
  765.       PTN->Ptr.off = PAR_ADR (obj);
  766.       break;
  767.     case CONST:
  768.     case NULL_VL:
  769.       prepare_CONST (Nod, V_PTN);
  770.       break;
  771.     case USERNAME:
  772.       prepare_USERNAME (PTN);
  773.       break;
  774.     default: /* operation */
  775.       if (Is_SQPredicate_Code (CODE_TRN (Nod)) && !VAL_HOLE (Nod))
  776. {
  777.   if (CODE_TRN (Nod) == SUBQUERY)
  778.     res = SQ_Comp (Nod, V_PTN, Depend, sq_cost);
  779.   else
  780.     res = (CODE_TRN (Nod) == EXISTS) ?
  781.       SQ_Exists (Nod, V_PTN, Depend, sq_cost) :
  782.               SQ_Quant (Nod, V_PTN, Depend, sq_cost);
  783.   return (VAL_HOLE (Nod) = res);
  784. }
  785.   
  786.       /* this tree could be loaded before */
  787.       if (VAL_HOLE (Nod) > 1)
  788. {
  789.   vmfree (V_PTN);
  790.           /* in multiused nodes field Depend may be = 0 *
  791.            * in this case dependency is in field Handle */
  792.   *Depend = V_PTR (VAL_HOLE (Nod), TRNode) -> Depend;
  793.           if (!(*Depend))
  794.             *Depend = V_PTR (VAL_HOLE (Nod), TRNode) -> Handle;
  795.   return VAL_HOLE (Nod);
  796. }
  797.   
  798.       PTN->code = CODE_TRN (Nod);
  799.       PTN->Arity = ARITY_TRN (Nod);
  800.       PTN->Ty = OPRN_TYPE (Nod);
  801.       PTN->Ptr.off = VNULL;
  802.     } /* switch */
  803.   V_Dn = (HAS_DOWN (Nod)) ? 
  804.     Tr_RecLoad (DOWN_TRN (Nod), &DnDepend, TRUE, NULL) : VNULL;
  805.   V_Rh = (RhNeed) ? 
  806.     Tr_RecLoad (RIGHT_TRN (Nod), &RhDepend, TRUE, NULL) : VNULL;
  807.   
  808.   PTN = V_PTR (V_PTN, TRNode);
  809.   PTN->Dn.off = V_Dn;
  810.   PTN->Rh.off = V_Rh;
  811.   PTN->Depend = BitOR (*Depend, DnDepend);
  812.   *Depend = BitOR (PTN->Depend, RhDepend);
  813.   PTN->Handle = 0;
  814.   return V_PTN;
  815. } /* TrRecLoad */
  816. VADR
  817. Pr_Constraints (VCBREF ScanNode, VADR Scan, i2_t oper, i4_t nm, i4_t *mlist)
  818.      /* makes the structure S_ConstrHeader in          *
  819.       * virtual memory for constraints  checking       *
  820.       * accordingly operation (INSERT, DELETE, UPDATE) *
  821.       * and mlist -columns' numbers (for UPDATE)       */
  822. {
  823.   Constr_Info *constr_info, *cur_constr, *next_constr, *last_constr;
  824.   char constr_need, *mod_cols;
  825.   i4_t i, j, all_cnstr_cnt = 0, cur_constr_cnt = 0, tab_colno, read_cnt = 0;
  826.   static i4_t ptrs_cnt = 0, mlist_fl_cnt = 0, read_fl_cnt = 0;
  827.   static VADR *ptrs = NULL;
  828.   static char *mlist_fl = NULL, *read_fl = NULL;
  829.   i2_t  constr_type;
  830.   VADR V_header = VNULL;
  831.   S_ConstrHeader *header = NULL;
  832.   VCBREF CurClm, Tab, View;
  833.   VADR V_constr_arr, *constr_arr, V_nums, V_types;
  834.   i4_t *nums;
  835.   sql_type_t *types;
  836.   
  837.   last_constr = NULL;
  838.   if (!ScanNode)
  839.     return VNULL;
  840.   Tab = COR_TBL (ScanNode);
  841.   if (!Tab)
  842.     return VNULL;
  843.   
  844.   P_VMALLOC (header, 1, S_ConstrHeader);
  845.   header->tab_col_num = tab_colno = TBL_NCOLS (Tab);
  846.   header->scan = Scan;
  847.   header->untabid = (TBL_TABID (Tab)).untabid;
  848.   
  849.   CHECK_ARR_SIZE (mlist_fl, mlist_fl_cnt, tab_colno, char);
  850.   if (oper == UPDATE)
  851.     {
  852.       bzero (mlist_fl, tab_colno);
  853.       for (i = 0; i < nm; i++)
  854. mlist_fl[mlist[i]] = TRUE;
  855.       read_cnt = nm;
  856.     }
  857.   else
  858.     {
  859.       if (oper == DELETE)
  860.         read_cnt = tab_colno;
  861.       for (i = 0; i < tab_colno; i++)
  862.         mlist_fl[i] = TRUE;
  863.     }
  864.   
  865.   CHECK_ARR_SIZE (read_fl,  read_fl_cnt,  tab_colno, char);
  866.   if (oper == INSERT)
  867.     bzero (read_fl,  tab_colno);
  868.   else
  869.     /* old values are needed for filling of statistic about columns */
  870.     bcopy (mlist_fl, read_fl, tab_colno);
  871.   
  872.   if (!CONSTR_INFO (Tab))
  873.     {
  874.       *(Constr_Info **) (&CONSTR_INFO (Tab)) =
  875. get_constraints ((TBL_TABID (Tab)).untabid, tab_colno);
  876.       if (!CONSTR_INFO (Tab))
  877. CONSTR_INFO (Tab) = 1;
  878.     }
  879.   constr_info = (CONSTR_INFO (Tab) == 1) ? NULL :
  880.     *(Constr_Info **) (&CONSTR_INFO (Tab));
  881.   
  882.   for (cur_constr = constr_info; cur_constr; cur_constr = next_constr)
  883.     {
  884.       all_cnstr_cnt++;
  885.       if (!(next_constr = cur_constr->next))
  886.         last_constr = cur_constr;
  887.     }
  888.   /* checking for VIEW constraints (it can exist  *
  889.    * if there is CHECK OPTION in VIEW definition) */
  890.   if ((View = COR_VIEW (ScanNode)))
  891.     {
  892.       Constr_Info *constr_view;
  893.       
  894.       TASSERT (CODE_TRN (View) == VIEW, View);
  895.       if (!CONSTR_INFO (View))
  896.         {
  897.           *(Constr_Info **) (&CONSTR_INFO (View)) =
  898.             get_constraints (VIEW_UNID (View), tab_colno);
  899.           if (!CONSTR_INFO (View))
  900.             CONSTR_INFO (View) = 1;
  901.         }
  902.       if (CONSTR_INFO (View) != 1)
  903.         {
  904.           constr_view = *(Constr_Info **) (&CONSTR_INFO (View));
  905.           for (cur_constr = constr_view; cur_constr;
  906.                cur_constr = cur_constr->next)
  907.             {
  908.               all_cnstr_cnt++;
  909.               assert (cur_constr->constr_type == CHECK);
  910.               cur_constr->constr_type = VIEW;
  911.             }
  912.           
  913.           if (last_constr)
  914.             last_constr->next = constr_view;
  915.           else
  916.             constr_info = constr_view;
  917.         }
  918.     }
  919.   
  920.   CHECK_ARR_SIZE (ptrs, ptrs_cnt, all_cnstr_cnt, VADR);
  921.   
  922.   for (cur_constr = constr_info; cur_constr; cur_constr = cur_constr->next)
  923.     {
  924.       constr_need = FALSE;
  925.       constr_type = cur_constr->constr_type;
  926.       mod_cols = cur_constr->mod_cols;
  927.       
  928.       if (oper == UPDATE)
  929. for (i = 0; i < nm; i++)
  930.           {
  931.             if (mod_cols[mlist[i]])
  932.               {/* this operation updates column from constraint */
  933.                 constr_need = TRUE;
  934.                 break;
  935.               }
  936.           }
  937.       else
  938. if ( (oper == DELETE && constr_type == REFERENCE) ||
  939.              (oper == INSERT && constr_type != REFERENCE))
  940.   constr_need = TRUE;
  941.       
  942.       if (constr_need)
  943. {
  944.   if (! (cur_constr->constr))
  945.     {
  946.       char *string = get_chconstr (cur_constr->conid, cur_constr->consize);
  947.       VADR constr_ptr, cur_seg, str_seg;
  948.               TRNode *t0;
  949.       
  950.       assert (constr_type == CHECK || constr_type == VIEW);
  951.       constr_ptr = VMALLOC (1, S_Constraint);
  952.       cur_constr->constr = constr_ptr;
  953.       V_PTR (constr_ptr, S_Constraint)->constr_type = constr_type;
  954.       cur_seg = get_vm_segment_id (0);
  955.       str_seg = link_segment (string, cur_constr->consize);
  956.               switch_to_segment (str_seg);
  957.               t0 = V_PTR (*V_PTR (4, VADR), TRNode);
  958.               switch_to_segment (cur_seg);
  959.               V_PTR (constr_ptr, S_Constraint)->object = load_tree (t0, cur_seg, str_seg);
  960.     }
  961.   
  962.   ptrs[cur_constr_cnt++] = cur_constr->constr;
  963.   
  964.   /* checking what columns must be readed from *
  965.    * scan to check current constraint :        */
  966.   for (i = 0; i < tab_colno; i++)
  967.     if (read_fl[i] < mod_cols[i] &&
  968. (!(mlist_fl[i]) || constr_type == REFERENCE))
  969.       {
  970. read_cnt++;
  971. read_fl[i] = mod_cols[i];
  972.       }
  973. }
  974.     } /* for: see all constraints */
  975.   
  976.   if (cur_constr_cnt)
  977.     {
  978.       P_VMALLOC (constr_arr, cur_constr_cnt, VADR);
  979.       bcopy (ptrs, constr_arr, cur_constr_cnt * sizeof (VADR));
  980.       header = V_PTR (V_header, S_ConstrHeader);
  981.       header->constr_num = cur_constr_cnt;
  982.       header->constr_arr = V_constr_arr;
  983.     }
  984.   /* if there aren't any constraints arrays with info      *
  985.    * about old values may be needed for statistic handling */
  986.   
  987.   V_nums = V_types = VNULL;
  988.   if (read_cnt)
  989.     {
  990.       P_VMALLOC (nums, read_cnt, i4_t);
  991.       P_VMALLOC (types, read_cnt, sql_type_t );
  992.       for (CurClm = TBL_COLS (Tab), j = 0; CurClm; CurClm = RIGHT_TRN (CurClm))
  993.         if (read_fl[i = COL_NO (CurClm)])
  994.           {
  995.             types[j] = COL_TYPE (CurClm);
  996.             nums[j++] = i;
  997.           }
  998.       header = V_PTR (V_header, S_ConstrHeader);
  999.     }
  1000.   header->old_vl_cnt = read_cnt;
  1001.   header->old_vl_nums = V_nums;
  1002.   header->old_vl_types = V_types;
  1003.   
  1004.   return V_header;
  1005. } /* Pr_Constraint */