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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  sorter.k  - set of routines to  create sorters
  3.  *              GNU SQL compiler
  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.
  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: sorter.k,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  29. #include <stdio.h>
  30. #include "cycler.h"
  31. #include "kitty.h"
  32. #include "optutil.h"
  33. #include "opt.h"
  34. #include <assert.h>
  35. #include "tassert.h"
  36. TXTREF
  37. find_sel(TXTREF qexpr)
  38. {
  39.   register TXTREF q = qexpr, s ;
  40.   enum token code;
  41.   while ( CODE_TRN(q) == UNION )
  42.     q = DOWN_TRN(q);
  43.   code = CODE_TRN(q);
  44.   TASSERT( code == QUERY || code == SUBQUERY, qexpr);
  45.   /*  selections from      query */
  46.   s = RIGHT_TRN (DOWN_TRN (q));
  47.   return s;
  48. }
  49. static void
  50. ob_to_nums(TXTREF dc)
  51. {
  52.   TXTREF sel = TNULL , ob, e;
  53.   i4_t    i;
  54.   for ( ob = DOWN_TRN(RIGHT_TRN(DOWN_TRN(dc)));ob;ob = RIGHT_TRN(ob))
  55.     switch(CODE_TRN(ob))
  56.       {
  57.       case SORT_COL:
  58.         if (!sel)
  59.           sel = DOWN_TRN (find_sel(DOWN_TRN(dc)));
  60.         for ( i=0,e = sel; e ; e = RIGHT_TRN(e),i++)
  61.           if ( trn_equal_p(e,SORT_CLM(ob)))
  62.             {
  63.               free_node(SORT_CLM(ob));
  64.               CODE_TRN(ob) = SORT_POS;
  65.               SORT_IND(ob) = i;
  66.               break;
  67.             }
  68.         if ( !e )
  69.           {
  70.             char str[100];
  71.             sprintf(str,"Attempt to sort by column(%s), unpresented in selection list",
  72.                     STRING(COL_NAME(OBJ_DESC(SORT_CLM(ob)))));
  73.             yyfatal(str);
  74.           }
  75.         break;
  76.       case SORT_POS:
  77.         break;
  78.       default:
  79.         yyfatal("unexpected node in order by clause");
  80.       }
  81. }
  82. static int
  83. is_empty_query(TXTREF qexpr)
  84. {
  85.   TXTREF sel_list,scol_list, col_list;
  86.   TXTREF t,s;
  87.   i4_t    i = 0;
  88.   if ( CODE_TRN(qexpr) != QUERY )
  89.     return 0;
  90.   if (TstF_TRN(qexpr,EMPTY_F))
  91.     return 1;
  92.   /* we shall check for
  93.      query
  94.        from t (list) on (tbl (list))
  95.        selection list
  96.    */
  97. #define CHECK(cond)    if (!(cond) ) return 0;
  98.   CHECK (ARITY_TRN(qexpr) == 2);
  99.   t = DOWN_TRN(qexpr);
  100.   CHECK( (CODE_TRN(t)==FROM) && (ARITY_TRN(t)==1));
  101.   s = TABL_DESC(DOWN_TRN(t));
  102.   t = RIGHT_TRN(t);
  103.   CHECK( (CODE_TRN(t)==SELECTION) && (ARITY_TRN(t) == TBL_NCOLS(COR_TBL(s))));
  104.   sel_list  = DOWN_TRN(t);
  105.   scol_list = COR_COLUMNS(s);
  106.   col_list  = TBL_COLS(COR_TBL(s));
  107.   while(col_list && scol_list && sel_list)
  108.     {
  109.       CHECK(OBJ_DESC(sel_list) == scol_list);
  110.       CHECK(COL_NO(scol_list) == COL_NO(col_list));
  111.       CHECK( COL_NO(scol_list) == i++);
  112.       sel_list  = RIGHT_TRN(sel_list );
  113.       scol_list = RIGHT_TRN(scol_list);
  114.       col_list  = RIGHT_TRN(col_list );
  115.     }
  116.   CHECK(!(col_list || scol_list || sel_list));
  117.   return 1;
  118. #undef CHECK
  119. }
  120. static TXTREF
  121. make_sorter(TXTREF qexpr,TXTREF sortlist,i4_t is_unique)
  122. {
  123.   TXTREF scan, sorter, sv, ce, sel ;
  124.   i4_t i;
  125.   sel = find_sel(qexpr);
  126.   if (!sortlist)
  127.     {
  128.       sv = gen_vect(ARITY_TRN(sel));
  129.       for( i = 0; i < VLEN(sv); i++)
  130.         VOP(sv,i).l = i;
  131.     }
  132.   else
  133.     {
  134.       sv = gen_vect(ARITY_TRN(sortlist));
  135.       for (i=0,ce = DOWN_TRN(sortlist);ce; ce = RIGHT_TRN(ce),i++)
  136.         VOP(sv,i).l = SORT_IND(ce);
  137.     }
  138.   if ( is_empty_query(qexpr))
  139.     {
  140.       TXTREF tbl; 
  141.       scan = COL_TBL(OBJ_DESC(DOWN_TRN(find_sel(qexpr))));
  142.       tbl = COR_TBL(scan);
  143.       if ( CODE_TRN(tbl) == TMPTABLE && CODE_TRN(VIEW_QUERY(tbl)) == SORTER )
  144.         { /* let's try to join nested sorter with required one */
  145.           i4_t j,k;
  146.           sorter = VIEW_QUERY(tbl);
  147.           ce = XTXT_TRN(sorter,0);
  148.           if (!sortlist && TstF_TRN(sorter,EMPTY_F))
  149.             { /* if order is unimportant now - swap sort vectors */
  150.               TXTREF cc = ce;
  151.               ce = sv;
  152.               sv = cc;
  153.             }
  154.           k = VLEN(ce);
  155.           for(i=VLEN(sv);i--;)
  156.             for(j=VLEN(ce);j--;)
  157.               if (VOP(ce,i).l == VOP(ce,j).l)
  158.                 {
  159.                   VOP(ce,j).l = -1;
  160.                   k--;
  161.                 }
  162.           if (k)
  163.             {
  164.               i = VLEN(sv);
  165.               sv = realloc_vect(sv, i + k);
  166.               for( j = 0; j < VLEN(ce); j++)
  167.                 if ( VOP(ce,j).l >=0 )
  168.                   {
  169.                     VOP(sv,i).l = VOP(ce,j).l;
  170.                     i++;
  171.                   }
  172.               assert(i == VLEN(sv));
  173.             }
  174.           XTXT_TRN(sorter,0) = sv; /* set new sort order to old sorter */
  175.           if (is_unique)
  176.             SetF_TRN(sorter,DISTINCT_F);
  177.           if (sortlist)
  178.             ClrF_TRN(sorter,EMPTY_F);
  179.           free_vect(ce);
  180.         }
  181.       else
  182.         {
  183.           if(CODE_TRN(tbl) == TABLE)
  184.             {
  185.               /* if we need to sort base table lets check for
  186.                * adequate index - may be it will much more usefull.
  187.                */
  188.               TXTREF ind;
  189.               for(ind = IND_INFO(tbl);ind;ind = RIGHT_TRN(ind))
  190.                 if (!is_unique || (CODE_TRN(ind)==PRIMARY) ||(CODE_TRN(ind)==UNIQUE))
  191.                   {
  192.                     TXTREF colptr;
  193.                     i4_t    i;
  194.                     for(colptr = DOWN_TRN(ind),i=0; colptr;
  195.                         i++,colptr= RIGHT_TRN(colptr))
  196.                       if (COL_NO(OBJ_DESC(colptr)) != VOP(sv,i).l)
  197.                         break;
  198.                     if(colptr==TNULL)
  199.                       break;
  200.                   }
  201.               if(ind) /* if there is usefull index - use it */
  202.                 {
  203.                   COR_IND_SP (scan) = ind;
  204.                   return qexpr;
  205.                 }
  206.               else /* organize explicit sorting of the whole table */
  207.                 {
  208.                   /* query (empty) { ..{..(scan "a" (table "A" ) )...}}
  209.                    * + (sorter (scan "b" (tmptable "B" (nil))))
  210.                    * ==>
  211.                    *    query (empty) { ..{.. (scan "a" (tmptable "B" (sorter
  212.                    *           (scan "b" (table "A" ))))) ...}}  
  213.                    */
  214.                   TXTREF s0,s1,tmp;
  215.                   sorter = #(Sorter <sv> <make_scan(DOWN_TRN(sel),TNULL)> );
  216.                   s0 = TABL_DESC(sorter);
  217.                   /*   scan      tblptr   from     query   */
  218.                   s1 = TABL_DESC(DOWN_TRN(DOWN_TRN(qexpr)));
  219.                   tmp = COR_TBL(TABL_DESC(sorter));
  220.                   COR_TBL(s0) = tbl;
  221.                   VIEW_QUERY(tmp) = sorter;
  222.                   /* table */
  223.                   COR_TBL   (s1) = tmp;
  224.                   { /* just to accurate scan naming */
  225.                     LTRLREF l = COR_NAME(s0);
  226.                     COR_NAME(s0) = COR_NAME(s1);
  227.                     COR_NAME(s1) = l;
  228.                   }
  229.                 }
  230.             }
  231.           else /* TMPTABLE */
  232.             {              
  233.               /* query (empty) { ..{.. (tmptable "A" (queryA)) ...}}
  234.                * + (sorter (scan (tmptable "B" (nil))))
  235.                * ==>
  236.                *    query (empty) { ..{.. (tmptable "A" (sorter
  237.                *           (scan(tmptable "B" (queryA))))) ...}}  
  238.                */
  239.               sorter = #(Sorter <sv> <make_scan(DOWN_TRN(sel),TNULL)> );
  240.               VIEW_QUERY(COR_TBL(TABL_DESC(sorter))) = VIEW_QUERY(tbl);
  241.               VIEW_QUERY(tbl) = sorter;
  242.             }
  243.           
  244.           if (is_unique)
  245.             SetF_TRN(sorter,DISTINCT_F);
  246.           if (!sortlist)
  247.             SetF_TRN(sorter,EMPTY_F);
  248.         }
  249.       return qexpr;
  250.     }
  251.   else
  252.     {
  253.       TXTREF new_query;
  254.       scan = make_scan(DOWN_TRN(sel),qexpr);
  255.       sorter = #(Sorter <sv> <scan> ) ;
  256.       if (is_unique)
  257.         SetF_TRN(sorter,DISTINCT_F);
  258.       if (!sortlist)
  259.         SetF_TRN(sorter,EMPTY_F);
  260.       new_query = query_via_tmp(sel,sorter);
  261.       if(CODE_TRN(qexpr)==SUBQUERY)
  262.         {
  263.           TXTREF sel;
  264.           
  265.           CODE_TRN(new_query) = SUBQUERY;
  266.           sel = RIGHT_TRN(DOWN_TRN(new_query));
  267.           TASSERT(CODE_TRN(sel)==SELECTION,new_query);
  268.           CODE_TRN(sel)=RESULT;
  269.           
  270.           CODE_TRN(qexpr) = QUERY;
  271.           sel = RIGHT_TRN(DOWN_TRN(qexpr));
  272.           TASSERT(CODE_TRN(sel)==RESULT,qexpr);
  273.           CODE_TRN(sel) = SELECTION;
  274.           
  275.         }
  276.       return new_query;
  277.     }
  278.   /* UNREACHABLE */
  279.   return TNULL;
  280. }
  281. static void
  282. check_union_selections(TXTREF un)
  283. {
  284.   TXTREF selection1, selection2, query;
  285.   /*           sel_list  selection  from      1st query  union   */
  286.   selection1 = DOWN_TRN (RIGHT_TRN (DOWN_TRN (DOWN_TRN  (un))));
  287.   for (query = DOWN_TRN(un); query; query = RIGHT_TRN(query))
  288.     {
  289.       TXTREF s1,s2;
  290.       i4_t    i; 
  291.       /*           sel_list  selection  from      1st query  union   */
  292.       selection2 = DOWN_TRN (RIGHT_TRN (DOWN_TRN (DOWN_TRN  (un))));
  293.       for(s1=selection1,s2=selection2, i=1 ;
  294.           s1 && s2;
  295.           s1 = RIGHT_TRN(s1), s2 = RIGHT_TRN(s2), i++)
  296.         if (!(is_casted(*node_type(s1),*node_type(s2)) &&
  297.               is_casted(*node_type(s2),*node_type(s1))))
  298.           {
  299.             char err[100];
  300.             sprintf(err,
  301.                     "types of %d element of union selection lists mismath",
  302.                     i);
  303.             file_pos = LOCATION_TRN(s2);
  304.             yyerror(err);
  305.           }
  306.       if(s1 || s2)
  307.           {
  308.             char err[100];
  309.             sprintf(err,"number of elements in union selection list mismath");
  310.             file_pos = LOCATION_TRN(selection2);
  311.             yyerror(err);
  312.           }
  313.     }
  314. }
  315. #define LD (f == CYCLER_LD)
  316. #define DR (f == CYCLER_DR)
  317. #define RL (f == CYCLER_RL)
  318. TXTREF
  319. sorting_proc(TXTREF n,i4_t f)
  320. {
  321.   switch(CODE_TRN(n))
  322.     {
  323.     case DECL_CURS:
  324.       if (LD && (ARITY_TRN(n) == 2))
  325.         ob_to_nums(n);
  326.       else if (DR && (ARITY_TRN(n) == 2))
  327.         {
  328.           TXTREF ob;
  329.           ob = RIGHT_TRN(DOWN_TRN(n));
  330.           RIGHT_TRN(DOWN_TRN(n)) = TNULL;
  331.           DOWN_TRN(n) = make_sorter(DOWN_TRN(n),ob,0);
  332.           ARITY_TRN(n) = 1;
  333.           free_tree(ob);
  334.         }
  335.       break;
  336.     case QUERY:
  337.     case SUBQUERY:
  338.       if (DR && TstF_TRN(n,DISTINCT_F))
  339.         {
  340.           ClrF_TRN(n,DISTINCT_F);
  341.           n = make_sorter (n, TNULL, 1);
  342.         }
  343.       break;
  344.     case UNION:
  345.       if(!DR)
  346.         break;
  347.       check_union_selections(n);
  348.       if (!TstF_TRN(n,ALL_F)) /* if sorting required */
  349.         {
  350.           /*----------------------------------------------------*
  351.            *   (union { (queryA) ... (queryZ)} )                *
  352.            * ==>                                                *
  353.            *   (sorter (union:all { (queryA) ... (queryZ) } ))  *
  354.            * or                                                 *
  355.            *   (union {                                         *
  356.            *     (tblptr (scan (tmptable (sorter (queryA)))))   *
  357.            *     ...                                            *
  358.            *     (tblptr (scan (tmptable (sorter (queryZ)))))   *
  359.            *   } )                                              *
  360.            *----------------------------------------------------*/
  361.           if(1)
  362.             {
  363.               SetF_TRN(n,ALL_F);
  364.               n = make_sorter (n, TNULL, 1);
  365.             }
  366.           else
  367.             {
  368.               TXTREF q, s = find_sel(n);
  369.               for( q = DOWN_TRN(n); q; q = RIGHT_TRN(q))
  370.                 {
  371.                   TXTREF r = RIGHT_TRN(q);
  372.                   TXTREF sc;
  373.                   TASSERT(CODE_TRN(q) == QUERY,n);
  374.                   q = make_sorter(q,TNULL,1);
  375.                   /*   scan      tblptr   from     query  */
  376.                   sc = TABL_DESC(DOWN_TRN(DOWN_TRN(q    )));
  377.                   free_tree(q);
  378.                   q =   #(TblPtr <sc>) ;
  379.                   TASSERT(CODE_TRN(q) == TBLPTR,n);
  380.                   RIGHT_TRN(q) = r;
  381.                 }
  382.               n = query_via_tmp( s, n);
  383.             }
  384.         }
  385.     default: break;
  386.     }
  387.   return n;
  388. }