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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  * subquery.c  - processing single nested queries                
  3.  *               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 Eugene W. Woynov
  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: subquery.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  29. #include <assert.h>
  30. #include "tassert.h"
  31. #include "global.h"
  32. #include "seman.h"
  33. #include "funall.h"
  34. #include "trlinter.h"
  35. #define SUBQ_PRINT      SEM_PRINT(SEM_OUTFILE,"n subquery...")
  36. #define SUBQ_PRINT_END  SEM_PRINT(SEM_OUTFILE,"OK")
  37. /********************************************************************/
  38. static void subq  __P((TXTREF));
  39. TXTREF rule_Type_N (i4_t *, TXTREF);
  40. TXTREF rule_Type_JA (i4_t *, TXTREF);
  41. static void change_scan  __P((TXTREF, TXTREF));
  42. static void change_scol  __P((TXTREF, TXTREF));
  43. static void copy_scan  __P((TXTREF));
  44. /********************************************************************/
  45. /*                         scan       tblptr    from      query     */     
  46. #define find_scan(query)  (TABL_DESC (DOWN_TRN (DOWN_TRN (query))))
  47. /********************************************************************/
  48. static i4_t    f_subq = 0;
  49. static TXTREF new_scan;
  50. static VCBREF local_vcb;
  51. /********************************************************************/
  52. CODERT 
  53. subq_main (TXTREF txtref)
  54. {
  55.   for (; txtref; txtref = RIGHT_TRN (txtref))
  56.     {
  57.       if (CODE_TRN (txtref) == CUR_AREA)
  58. local_vcb = XVCB_TRN (DOWN_TRN (txtref), 7);
  59.       else
  60. local_vcb = XVCB_TRN (txtref, 7);
  61.       subq (txtref);
  62.     }
  63.   if (f_subq)
  64.     SUBQ_PRINT_END;
  65.   if (s_e_error)
  66.     {
  67.       char *s = "s";
  68.       errors += s_e_error;
  69.       if (s_e_error == 1)
  70.         s = "";
  71.       SEM_PRINT (SEM_OUTFILE, "nThere was %d error%s at ", s_e_error, s);
  72.       return (SQL_ERROR);
  73.     }
  74.   
  75.   return (SQL_SUCCESS);
  76. } /* end subq_main */
  77. /**********************************************************************/
  78. /**********************************************************************/
  79. static void
  80. subq (TXTREF txtref)
  81. {
  82.   TXTREF curr_txtref;
  83.   i4_t arity;
  84.   enum token code;
  85.   i4_t done;
  86.   
  87.   if (txtref) return;
  88.   if (!HAS_DOWN(txtref))
  89.     return;
  90.   for (arity = (i4_t) ARITY_TRN (txtref), txtref = DOWN_TRN (txtref);
  91.        arity > 0;
  92.        arity--, txtref = RIGHT_TRN (txtref))
  93.     {
  94.       code = CODE_TRN (txtref);
  95.       if (code == QUERY ||
  96.   code == SUBQUERY)
  97. if (TstF_TRN (txtref, SUBQUERY_F))
  98.   {
  99.     rule_Type_N (&done, txtref);
  100.     if (done)
  101.       {
  102. if (!f_subq)
  103.   SUBQ_PRINT;
  104.                 f_subq = 1;
  105. SEM_PRINT (SEM_OUTFILE, " *NJ* ");
  106. ClrF_TRN (txtref, SUBQUERY_F);
  107.       }
  108.     curr_txtref = rule_Type_JA (&done, txtref);
  109.     if (done)
  110.       {
  111. if (!f_subq)
  112.   SUBQ_PRINT;
  113.                 f_subq = 1;
  114. SEM_PRINT (SEM_OUTFILE, " *JA* ");
  115. copy_scan (VCB_ROOT);
  116. change_scan (curr_txtref, find_scan (curr_txtref));
  117.       }
  118.   }
  119.       if (HAS_DOWN(txtref))
  120. subq (txtref);
  121.     }
  122. } /* end subq */
  123. /********************************************************************/
  124. static void
  125. copy_scan (TXTREF txtref)
  126. {
  127.   VCBREF v, scol;
  128.   new_scan = gen_node (SCAN);
  129.   COR_TBL (new_scan) = txtref;
  130.   COR_NEXT (new_scan) = RIGHT_TRN (local_vcb);
  131.   RIGHT_TRN (local_vcb) = new_scan;
  132. /* copy columns chain */
  133.   for (v = TBL_COLS (VCB_ROOT); v; v = COL_NEXT (v))
  134.     {
  135.       scol = gen_node (SCOLUMN);
  136.       COL_NEXT (scol) = COR_COLUMNS (new_scan);
  137.       COR_COLUMNS (new_scan) = scol;
  138.       COL_NO (scol) = COL_NO (v);
  139.       COL_TYPE (scol) = COL_TYPE (v);
  140.       COL_TBL (scol) = new_scan /*COL_TBL(v)*/ ;
  141.     }
  142. }
  143. /********************************************************************/
  144. static void
  145. change_scan (TXTREF query, TXTREF scan)
  146. {
  147.   TXTREF p;
  148.   /*scan     tblptr    from      */     
  149.   TABL_DESC (DOWN_TRN (DOWN_TRN (query))) = new_scan;
  150.   p = gen_node (COLPTR);
  151.   OBJ_DESC (p) = COR_COLUMNS (new_scan);
  152.   /*1st col  selection  from      */     
  153.   DOWN_TRN  (RIGHT_TRN (DOWN_TRN (query))) = p;
  154.   change_scol (query, scan);
  155. }
  156. /********************************************************************/
  157. static void
  158. change_scol (TXTREF query, TXTREF scan)
  159. {
  160.   TXTREF t;
  161.   for (t = DOWN_TRN (query); t; t = RIGHT_TRN (t))
  162.     {
  163.       if (HAS_DOWN(t))
  164. change_scol (t, scan);
  165.       if (CODE_TRN (t) == COLPTR)
  166. if (COL_TBL (OBJ_DESC (t)) == scan)
  167.   OBJ_DESC (t) = COL_NEXT (COR_COLUMNS (new_scan));
  168.     }
  169. }
  170. /************************************************************************/