1
/* Copyright (C) 2000-2006 MySQL AB
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.
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.
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 */
18
OLAP implementation by Sinisa Milivojevic <sinisa@mysql.com>
19
Inspired by code submitted by Srilakshmi <lakshmi@gdit.iiit.net>
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.
24
In 4.1 we will replace this with a working, superior implementation
28
#ifdef DISABLED_UNTIL_REWRITTEN_IN_4_1
30
#ifdef USE_PRAGMA_IMPLEMENTATION
31
#pragma implementation // gcc: Class implementation
34
#include "mysql_priv.h"
35
#include "sql_select.h"
38
/****************************************************************************
39
Functions that recursively actually creates new SELECT's
40
Returns 0 if OK, 1 if error, -1 if error already printed to client
41
****************************************************************************/
44
static int make_new_olap_select(LEX *lex, SELECT_LEX *select_lex, List<Item> new_fields)
47
Item *item, *new_item;
48
Item_null *constant= new Item_null("ALL");
50
SELECT_LEX *new_select = (SELECT_LEX *) thd->memdup((char*) select_lex, sizeof(*select_lex));
53
lex->last_selects->next=new_select;
54
new_select->linkage=OLAP_TYPE;
55
new_select->olap=NON_EXISTING_ONE;
56
new_select->group_list.elements=0;
57
new_select->group_list.first=(uchar *)0;
58
new_select->group_list.next=(uchar **)&new_select->group_list.first;
61
List_iterator<Item> list_it(select_lex->item_list);
62
List_iterator<Item> new_it(new_fields);
64
while ((item=list_it++))
67
if (item->type()==Item::FIELD_ITEM)
69
Item_field *iif = (Item_field *)item;
71
while ((new_item=new_it++))
73
if (new_item->type()==Item::FIELD_ITEM &&
74
!strcmp(((Item_field*)new_item)->table_name,iif->table_name) &&
75
!strcmp(((Item_field*)new_item)->field_name,iif->field_name))
78
((Item_field*)new_item)->db_name=iif->db_name;
79
Item_field *new_one=new Item_field(&select_lex->context,
80
iif->db_name, iif->table_name, iif->field_name);
81
privlist.push_back(new_one);
82
if (add_to_list(new_select->group_list,new_one,1))
90
if (item->type() == Item::FIELD_ITEM)
91
privlist.push_back(constant);
93
privlist.push_back((Item*)thd->memdup((char *)item,item->size_of()));
96
new_select->item_list=privlist;
98
lex->last_selects = new_select;
102
/****************************************************************************
103
Functions that recursively creates combinations of queries for OLAP
104
Returns 0 if OK, 1 if error, -1 if error already printed to client
105
****************************************************************************/
107
static int olap_combos(List<Item> old_fields, List<Item> new_fields, Item *item, LEX *lex,
108
SELECT_LEX *select_lex, int position, int selection, int num_fields,
112
if (position == num_new_fields)
115
new_fields.push_front(item);
116
sl_return = make_new_olap_select(lex, select_lex, new_fields);
121
new_fields.push_front(item);
122
while ((num_fields - num_new_fields >= selection - position) && !sl_return)
124
item = old_fields.pop();
125
sl_return = olap_combos(old_fields, new_fields, item, lex, select_lex, position+1, ++selection, num_fields, num_new_fields);
132
/****************************************************************************
133
Top level function for converting OLAP clauses to multiple selects
134
This is also a place where clauses treatment depends on OLAP type
135
Returns 0 if OK, 1 if error, -1 if error already printed to client
136
****************************************************************************/
138
int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
140
List<Item> item_list_copy, new_item_list;
141
item_list_copy.empty();
142
new_item_list.empty();
143
int count=select_lex->group_list.elements;
147
lex->last_selects=select_lex;
149
for (ORDER *order=(ORDER *)select_lex->group_list.first ; order ; order=order->next)
150
item_list_copy.push_back(*(order->item));
152
List<Item> all_fields(select_lex->item_list);
155
if (setup_tables(lex->thd, &select_lex->context, &select_lex->top_join_list,
156
(TABLE_LIST *)select_lex->table_list.first
157
&select_lex->leaf_tables, FALSE) ||
158
setup_fields(lex->thd, 0, select_lex->item_list, MARK_COLUMNS_READ,
160
setup_fields(lex->thd, 0, item_list_copy, MARK_COLUMNS_READ,
164
if (select_lex->olap == CUBE_TYPE)
166
for ( int i=count-1; i>=0 && !sl_return; i--)
167
sl_return=olap_combos(item_list_copy, new_item_list, (Item *)0, lex, select_lex, 0, 0, count, i);
169
else if (select_lex->olap == ROLLUP_TYPE)
171
for ( int i=count-1; i>=0 && !sl_return; i--)
174
item_list_copy.pop();
175
List_iterator<Item> it(item_list_copy);
176
new_item_list.empty();
177
while ((item = it++))
178
new_item_list.push_front(item);
179
sl_return=make_new_olap_select(lex, select_lex, new_item_list);
183
sl_return=1; // impossible
187
#endif /* DISABLED_UNTIL_REWRITTEN_IN_4_1 */