~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_olap.cc

  • Committer: Stewart Smith
  • Date: 2009-05-12 05:56:00 UTC
  • mfrom: (1008 drizzle)
  • mto: (1014.2.2 mordred)
  • mto: This revision was merged to the branch mainline in revision 1015.
  • Revision ID: stewart@flamingspork.com-20090512055600-4gg3jgx2bqt9wn5f
merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
16
 
 
17
 
/*
18
 
  OLAP implementation by Sinisa Milivojevic <sinisa@mysql.com>
19
 
  Inspired by code submitted by Srilakshmi <lakshmi@gdit.iiit.net>
20
 
 
21
 
  The ROLLUP code in this file has to be complitely rewritten as it's
22
 
  not good enough to satisfy the goals of MySQL.
23
 
 
24
 
  In 4.1 we will replace this with a working, superior implementation
25
 
  of ROLLUP.
26
 
*/
27
 
 
28
 
#ifdef DISABLED_UNTIL_REWRITTEN_IN_4_1
29
 
#include <drizzled/server_includes.h>
30
 
#include <drizzled/sql_select.h>
31
 
 
32
 
 
33
 
/****************************************************************************
34
 
  Functions that recursively actually creates new SELECT's
35
 
  Returns 0 if OK, 1 if error, -1 if error already printed to client
36
 
****************************************************************************/
37
 
 
38
 
 
39
 
static int make_new_olap_select(LEX *lex, Select_Lex *select_lex, List<Item> new_fields)
40
 
{
41
 
  Session       *session=current_session;
42
 
  Item *item, *new_item;
43
 
  Item_null *constant= new Item_null("ALL");
44
 
 
45
 
  Select_Lex *new_select = (Select_Lex *) session->memdup((char*) select_lex, sizeof(*select_lex));
46
 
  if (!new_select)
47
 
    return 1;
48
 
  lex->last_selects->next=new_select;
49
 
  new_select->linkage=OLAP_TYPE;
50
 
  new_select->olap=NON_EXISTING_ONE;
51
 
  new_select->group_list.elements=0;
52
 
  new_select->group_list.first=(unsigned char *)0;
53
 
  new_select->group_list.next=(unsigned char **)&new_select->group_list.first;
54
 
  List<Item> privlist;
55
 
 
56
 
  List_iterator<Item> list_it(select_lex->item_list);
57
 
  List_iterator<Item> new_it(new_fields);
58
 
 
59
 
  while ((item=list_it++))
60
 
  {
61
 
    bool not_found= true;
62
 
    if (item->type()==Item::FIELD_ITEM)
63
 
    {
64
 
      Item_field *iif = (Item_field *)item;
65
 
      new_it.rewind();
66
 
      while ((new_item=new_it++))
67
 
      {
68
 
        if (new_item->type()==Item::FIELD_ITEM &&
69
 
            !strcmp(((Item_field*)new_item)->table_name,iif->table_name) &&
70
 
            !strcmp(((Item_field*)new_item)->field_name,iif->field_name))
71
 
        {
72
 
          not_found= 0;
73
 
          ((Item_field*)new_item)->db_name=iif->db_name;
74
 
          Item_field *new_one=new Item_field(&select_lex->context,
75
 
                                             iif->db_name, iif->table_name, iif->field_name);
76
 
          privlist.push_back(new_one);
77
 
          if (add_to_list(new_select->group_list,new_one,1))
78
 
            return 1;
79
 
          break;
80
 
        }
81
 
      }
82
 
    }
83
 
    if (not_found)
84
 
    {
85
 
      if (item->type() == Item::FIELD_ITEM)
86
 
        privlist.push_back(constant);
87
 
      else
88
 
        privlist.push_back((Item*)session->memdup((char *)item,item->size_of()));
89
 
    }
90
 
  }
91
 
  new_select->item_list=privlist;
92
 
 
93
 
  lex->last_selects = new_select;
94
 
  return 0;
95
 
}
96
 
 
97
 
/****************************************************************************
98
 
  Functions that recursively creates combinations of queries for OLAP
99
 
  Returns 0 if OK, 1 if error, -1 if error already printed to client
100
 
****************************************************************************/
101
 
 
102
 
static int  olap_combos(List<Item> old_fields, List<Item> new_fields, Item *item, LEX *lex,
103
 
                              Select_Lex *select_lex, int position, int selection, int num_fields,
104
 
                              int num_new_fields)
105
 
{
106
 
  int sl_return = 0;
107
 
  if (position == num_new_fields)
108
 
  {
109
 
    if (item)
110
 
      new_fields.push_front(item);
111
 
    sl_return = make_new_olap_select(lex, select_lex, new_fields);
112
 
  }
113
 
  else
114
 
  {
115
 
    if (item)
116
 
      new_fields.push_front(item);
117
 
    while ((num_fields - num_new_fields >= selection - position) && !sl_return)
118
 
    {
119
 
      item = old_fields.pop();
120
 
      sl_return = olap_combos(old_fields, new_fields, item, lex, select_lex, position+1, ++selection, num_fields, num_new_fields);
121
 
    }
122
 
  }
123
 
  return sl_return;
124
 
}
125
 
 
126
 
 
127
 
/****************************************************************************
128
 
  Top level function for converting OLAP clauses to multiple selects
129
 
  This is also a place where clauses treatment depends on OLAP type
130
 
  Returns 0 if OK, 1 if error, -1 if error already printed to client
131
 
****************************************************************************/
132
 
 
133
 
int handle_olaps(LEX *lex, Select_Lex *select_lex)
134
 
{
135
 
  List<Item> item_list_copy, new_item_list;
136
 
  item_list_copy.empty();
137
 
  new_item_list.empty();
138
 
  int count=select_lex->group_list.elements;
139
 
  int sl_return=0;
140
 
 
141
 
 
142
 
  lex->last_selects=select_lex;
143
 
 
144
 
  for (ORDER *order=(ORDER *)select_lex->group_list.first ; order ; order=order->next)
145
 
    item_list_copy.push_back(*(order->item));
146
 
 
147
 
  List<Item>    all_fields(select_lex->item_list);
148
 
 
149
 
 
150
 
  if (setup_tables(lex->session, &select_lex->context, &select_lex->top_join_list,
151
 
                   (TableList *)select_lex->table_list.first
152
 
                   &select_lex->leaf_tables, false) ||
153
 
      setup_fields(lex->session, 0, select_lex->item_list, MARK_COLUMNS_READ,
154
 
                   &all_fields,1) ||
155
 
      setup_fields(lex->session, 0, item_list_copy, MARK_COLUMNS_READ,
156
 
                   &all_fields, 1))
157
 
    return -1;
158
 
 
159
 
  if (select_lex->olap == CUBE_TYPE)
160
 
  {
161
 
    for ( int i=count-1; i>=0 && !sl_return; i--)
162
 
      sl_return=olap_combos(item_list_copy, new_item_list, (Item *)0, lex, select_lex, 0, 0, count, i);
163
 
  }
164
 
  else if (select_lex->olap == ROLLUP_TYPE)
165
 
  {
166
 
    for ( int i=count-1; i>=0 && !sl_return; i--)
167
 
    {
168
 
      Item *item;
169
 
      item_list_copy.pop();
170
 
      List_iterator<Item> it(item_list_copy);
171
 
      new_item_list.empty();
172
 
      while ((item = it++))
173
 
        new_item_list.push_front(item);
174
 
      sl_return=make_new_olap_select(lex, select_lex, new_item_list);
175
 
    }
176
 
  }
177
 
  else
178
 
    sl_return=1; // impossible
179
 
  return sl_return;
180
 
}
181
 
 
182
 
#endif /* DISABLED_UNTIL_REWRITTEN_IN_4_1 */