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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  synlib.c - codegenerator library of GNU SQL server
  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 Konstantin Dyshlevoi
  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: dkv@ispras.ru
  25.  *            gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: synlib.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  29. #include "global.h"
  30. #include "syndef.h"
  31. typedef struct {
  32.   TXTREF tree;
  33.   MASK   tree_deps;
  34.   char   col_flag; /* = TRUE if this tree - contains only COLPTR & SCOLUMN  */
  35.   char   sign;     /* = TRUE if sign of tree - '+' or FALSE in another case */
  36. } add_elem;
  37. static add_elem *add_elem_arr;
  38. static i4_t       add_elem_max;
  39. static i4_t       add_elem_num;
  40. #define ARR_DELTA 5
  41. MASK
  42. see_deps (TXTREF Node, MASK *SQ_deps, float *SQ_cost)
  43. /* Fuction returns dependency of the tree with root = Node              *
  44.  * and put to SQ_deps - dependency of SubQuery (if exists in this tree) *
  45.  * and to SQ_cost - estimation of the cost for this  SubQuery           */
  46. {
  47.   TXTREF cur_son;
  48.   MASK cur_sq_deps, deps = 0, cur_deps;
  49.   float cur_sq_cost;
  50.  
  51.   *SQ_deps = 0;
  52.   *SQ_cost = 0.0;
  53.   
  54.   if (Node)
  55.     if (CODE_TRN (Node) == COLPTR)
  56.       deps = COR_MASK (COL_TBL (OBJ_DESC (Node)));
  57.     else
  58.       if (Is_SQPredicate_Code (CODE_TRN (Node)))
  59.         {
  60.           Tr_RecLoad (Node, SQ_deps, 0, SQ_cost);
  61.           deps = *SQ_deps;
  62.         }
  63.       else
  64.         if (HAS_DOWN (Node))
  65.           for (cur_son = DOWN_TRN (Node);
  66.                cur_son; cur_son = RIGHT_TRN (cur_son))
  67.             {
  68.               cur_deps = see_deps (cur_son, &cur_sq_deps, &cur_sq_cost);
  69.               deps = BitOR (deps, cur_deps);
  70.               *SQ_deps = BitOR (*SQ_deps, cur_sq_deps);
  71.               *SQ_cost += cur_sq_cost;
  72.             }
  73.   
  74.   return deps;
  75. } /* see_deps */
  76. MASK
  77. see_add_elems (TXTREF Node, char sign, MASK *SQ_deps, float *SQ_cost)
  78. /* Is used for making of array 'add_elem_arr' -     *
  79.  * dividing of tree on arguments of 'ADD' operation *
  80.  * This function doesn't change tree-argument       *
  81.  * Fuction returns the same results as  see_deps () */
  82. {
  83.   MASK cur_sq_deps, deps = 0, cur_deps;
  84.   float cur_sq_cost;
  85.   TXTREF cur_son;
  86.   enum token code = CODE_TRN (Node);
  87.   add_elem *elem;
  88.   *SQ_deps = 0;
  89.   *SQ_cost = 0.0;
  90.   
  91.   switch (code)
  92.     {
  93.     case ADD :
  94.     case SUB :
  95.       for (cur_son = DOWN_TRN (Node);
  96.            cur_son; cur_son = RIGHT_TRN (cur_son))
  97.         {
  98.           cur_deps =
  99.             see_add_elems (cur_son,
  100.                            (code == ADD || cur_son == DOWN_TRN (Node)) ?
  101.                            sign : 1 - sign, &cur_sq_deps, &cur_sq_cost);
  102.           deps = BitOR (deps, cur_deps);
  103.           *SQ_deps = BitOR (*SQ_deps, cur_sq_deps);
  104.           *SQ_cost += cur_sq_cost;
  105.         }
  106.       break;
  107.       
  108.     case UMINUS :
  109.       deps = see_add_elems (DOWN_TRN (Node), 1 - sign, SQ_deps, SQ_cost);
  110.       break;
  111.       
  112.     case NOOP:
  113.       deps = see_add_elems (DOWN_TRN (Node), sign, SQ_deps, SQ_cost);
  114.       break;
  115.     default :
  116.       CHECK_ARR_ELEM (add_elem_arr, add_elem_max,
  117.                       add_elem_num, ARR_DELTA, add_elem);
  118.       elem = add_elem_arr + (add_elem_num++);
  119.       elem->tree = Node;
  120.       deps = elem->tree_deps = see_deps (Node, SQ_deps, SQ_cost);
  121.       elem->col_flag = (code == COLPTR);
  122.       elem->sign = sign;
  123.     }
  124.   
  125.   return deps;
  126. } /* see_add_elems */
  127. int
  128. SP_Extract (TXTREF Node, MASK *TblBits, i4_t TblNum, Simp_Pred_Info ** Result)
  129.      /* making attempt to find interpretations of disjuncts *
  130.       * as simple predicates and filling information about  *
  131.       * disjunct into array *Result. This function returns  *
  132.       * elements number in this array = number of disjuncts *
  133.       * Important is that this function change where-tree   *
  134.       * onto array *Result so that tree with root 'Node'    *
  135.       * can't be used after this functin finished           */
  136. {
  137.   i4_t k, dis_num = 1, add_num, arr_num;
  138.   TXTREF cur_dis = Node, next_dis, right_list,
  139.     right_node, comp_node, left_node, col_tree;
  140.   Simp_Pred_Info *arr;
  141.   enum token code;
  142.   char sign;
  143.   MASK left_deps, right_deps, left_sq_deps, right_sq_deps, deps;
  144.   float left_cost, right_cost;
  145.   add_elem *elem;
  146.   add_elem *old_add_elem_arr = add_elem_arr;
  147.   i4_t       old_add_elem_max = add_elem_max;
  148.   i4_t       old_add_elem_num = add_elem_num;
  149.   enum token opp_code [] = { /* EQU */ EQU,
  150.                              /* NE  */ NE,
  151.                              /* LE  */ GE,
  152.                              /* GE  */ LE,
  153.                              /* LT  */ GT,
  154.                              /* GT  */ LT  };
  155.   
  156.   if (!Node)
  157.     {
  158.       *Result = NULL;
  159.       return 0;
  160.     }
  161.   add_elem_arr = NULL;
  162.   add_elem_max = 0;
  163.   
  164.   if (CODE_TRN (Node) == AND)
  165.     {
  166.       dis_num = ARITY_TRN (Node);
  167.       cur_dis = DOWN_TRN (Node);
  168.     }
  169.   arr = *Result = TYP_ALLOC (dis_num, Simp_Pred_Info);
  170.   for (arr_num = 0; cur_dis; cur_dis = next_dis, arr_num++)
  171.     {
  172.       next_dis = RIGHT_TRN (cur_dis);
  173.       RIGHT_TRN (cur_dis) =  TNULL;
  174.       code = CODE_TRN (cur_dis);
  175.       if (Is_Comp_Code (code) && code != NE)
  176.         /* may be current disjunct can be considered as simple predicate */
  177.         {
  178.           add_elem_num = 0;
  179.           left_deps = see_add_elems (DOWN_TRN (cur_dis), TRUE,
  180.                                      &left_sq_deps, &left_cost);
  181.           right_deps = see_add_elems (RIGHT_TRN (DOWN_TRN (cur_dis)),
  182.                                       FALSE, &right_sq_deps, &right_cost);
  183.           arr[arr_num].Depend = BitOR (left_deps, right_deps);
  184.           arr[arr_num].SQ_deps = BitOR (left_sq_deps, right_sq_deps);
  185.           arr[arr_num].SQ_cost = left_cost + right_cost;
  186.           
  187.           for (add_num = 0; add_num < add_elem_num; add_num++)
  188.             if (add_elem_arr[add_num].col_flag)
  189.               {
  190.                 deps = add_elem_arr[add_num].tree_deps;
  191.                 /* checking: if column of current add element *
  192.                  * belongs to table from current query        */
  193.                 for (k = 0; k < TblNum; k++)
  194.                   if (TblBits[k] == deps)
  195.                     break;
  196.                 if (k == TblNum)
  197.                   /* column of current add element belongs to external table */
  198.                   continue;
  199.                 /* checking: if this column isn't used in other add elements */
  200.                 for (k = 0; k < add_elem_num; k++)
  201.                   if (k != add_num && BitAND (deps, add_elem_arr[k].tree_deps))
  202.                     /* there is another ADD argument (number k)  *
  203.                      * depends on the same table as checking     *
  204.                      * column (from add_num-th argument) is from */
  205.                     break;
  206.                 if (k == add_elem_num)
  207.                   /* checking column can be the base of simple predicate */
  208.                   {
  209.                     (arr[arr_num].SP_Num)++;
  210.                     sign = add_elem_arr[add_num].sign;
  211.                       
  212.                     /* node for compare operation (comp_node) making */
  213.                     comp_node = gen_node ((sign) ? code : opp_code [code - EQU]);
  214.                     RIGHT_TRN (comp_node) = arr[arr_num].SP_Trees;
  215.                     arr[arr_num].SP_Trees = comp_node;
  216.                     OPRN_TYPE (comp_node) = OPRN_TYPE (cur_dis);
  217.                     ARITY_TRN (comp_node) = 2;
  218.                     /* left part of compare operation making */
  219.                     col_tree = add_elem_arr[add_num].tree;
  220.                     left_node = gen_node (NOOP);
  221.                     DOWN_TRN  (left_node) = col_tree;
  222.                     ARITY_TRN (left_node) = 1;
  223.                     OPRN_TYPE (left_node) = COL_TYPE (OBJ_DESC (col_tree));
  224.                     DOWN_TRN  (comp_node) = left_node;
  225.                     RIGHT_TRN (col_tree) = TNULL;
  226.                       
  227.                     /* right part of compare operation making */
  228.                     right_list = TNULL;
  229.                     for (k = 0, elem = add_elem_arr; k < add_elem_num; k++, elem++)
  230.                       if (k != add_num)
  231.                         {
  232.                           RIGHT_TRN (elem->tree) = TNULL;
  233.                           right_node = gen_node ((sign - elem->sign) ? NOOP : UMINUS);
  234.                           DOWN_TRN  (right_node) = elem->tree;
  235.                           ARITY_TRN (right_node) = 1;
  236.                           RIGHT_TRN (right_node) = right_list;
  237.                           right_list = right_node;
  238.                         }
  239.                     if (add_elem_num > 2)
  240.                       {
  241.                         right_node = gen_node (ADD);
  242.                         DOWN_TRN  (right_node) = right_list;
  243.                         ARITY_TRN (right_node) = add_elem_num - 1;
  244.                         right_list = right_node;
  245.                       }
  246.                     RIGHT_TRN (left_node) = right_list;
  247.                   }
  248.               }
  249.           if (!(arr[arr_num].SP_Num))
  250.             arr[arr_num].SP_Trees = cur_dis;
  251.         }
  252.       else
  253.         /* current disjunct can't be considered as simple predicate */
  254.         {
  255.           arr[arr_num].Depend = see_deps (cur_dis, &(arr[arr_num].SQ_deps),
  256.                                           &(arr[arr_num].SQ_cost));
  257.           arr[arr_num].SP_Num = ((code == ISNULL) ||
  258.                                  (code == ISNOTNULL)) ? 1 : 0;
  259.           arr[arr_num].SP_Trees = cur_dis;
  260.         }
  261.     } /* for arr_num */
  262.   
  263.   add_elem_arr = old_add_elem_arr;
  264.   add_elem_max = old_add_elem_max;
  265.   add_elem_num = old_add_elem_num;
  266.   return dis_num;
  267. } /* SP_Extract */
  268. #undef ARR_DELTA