summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Docs/manual.texi136
-rw-r--r--mysql-test/r/olap.result138
-rw-r--r--mysql-test/t/olap.test22
-rw-r--r--sql/item.h21
-rw-r--r--sql/item_cmpfunc.h15
-rw-r--r--sql/item_func.h23
-rw-r--r--sql/item_strfunc.h26
-rw-r--r--sql/item_sum.h17
-rw-r--r--sql/item_timefunc.h10
-rw-r--r--sql/item_uniq.h2
-rw-r--r--sql/lex.h4
-rw-r--r--sql/procedure.h4
-rw-r--r--sql/sql_olap.cc181
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_union.cc1
-rw-r--r--sql/sql_yacc.yy22
16 files changed, 612 insertions, 12 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi
index 83531aaab47..96a1d70ffef 100644
--- a/Docs/manual.texi
+++ b/Docs/manual.texi
@@ -49259,6 +49259,12 @@ New client-server protocol for 4.0
@item
Multi-table @code{DELETE}/@code{UPDATE}
@item
+derived tables
+@item
+user resources management
+@item
+OLAP functionality
+@item
The @code{MySQLGUI} client.
@item
Maintainer of @code{MySQL++}.
@@ -49689,8 +49695,138 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
@item
Fixed a bug that made the pager option in the mysql client non-functional.
@end itemize
+@item
+Added OLAP functionality.
+
+Arjen , please add the following text somewhere appropriate in the
+text above:
+
+-------------------------------------------------------------------------
+
+Documentation for OLAP extension
+
+Introduction
+------------
+
+MySQL will first support CUBE and ROLLUP operators from entire OLAP
+functionality.
+
+The CUBE and ROLLUP extensions to SQL make querying and reporting
+easier in data warehousing environments. ROLLUP creates subtotals at
+increasing levels of aggregation, from the most detailed up to a grand
+total. CUBE is an extension similar to ROLLUP, enabling a single
+statement to calculate all possible combinations of subtotals.
+Syntax:
+------
+
+The syntax supported by the enhanced mysql for CUBE and ROLLUP
+operators.
+
+CUBE
+----
+
+SELECT field1, field2, ... AGGR(fieldn) FROM
+table GROUP BY field1, field2 field(n-1) WITH CUBE
+
+This would generate the aggregates with group bys of all the
+combinations of dimensions.
+
+ROLLUP:
+-----
+
+ SELECT field1, field2, ... AGGR(fieldn) FROM table
+ GROUP BY field1, field2 field(n-1) WITH ROLLUP
+
+Example:
+-------
+
+mysql> select * from sales;
++------------+---------------+------+--------+
+| product | country | year | profit |
++------------+---------------+------+--------+
+| Computer | India | 2000 | 1200 |
+| TV | United States | 1999 | 150 |
+| Calculator | United States | 1999 | 50 |
+| Computer | United States | 1999 | 1500 |
+| Computer | United States | 2000 | 1500 |
+| TV | United States | 2000 | 150 |
+| TV | India | 2000 | 100 |
+| TV | India | 2000 | 100 |
+| Calculator | United States | 2000 | 75 |
+| Calculator | India | 2000 | 75 |
+| TV | India | 1999 | 100 |
+| Computer | India | 1999 | 1200 |
+| Computer | United States | 2000 | 1500 |
+| Calculator | United States | 2000 | 75 |
++------------+---------------+------+--------+
+14 rows in set (0.00 sec)
+
+
+
+mysql> Select sales.product, sales.country , sales.year, sum(profit) from
+sales group by product, country, year with cube;
+
++------------+---------------+------+-------------+
+| product | country | year | sum(profit) |
++------------+---------------+------+-------------+
+| Calculator | India | 2000 | 75 |
+| Calculator | United States | 1999 | 50 |
+| Calculator | United States | 2000 | 150 |
+| Computer | India | 1999 | 1200 |
+| Computer | India | 2000 | 1200 |
+| Computer | United States | 1999 | 1500 |
+| Computer | United States | 2000 | 3000 |
+| TV | India | 1999 | 100 |
+| TV | India | 2000 | 200 |
+| TV | United States | 1999 | 150 |
+| TV | United States | 2000 | 150 |
+| ALL | India | 1999 | 1300 |
+| ALL | India | 2000 | 1475 |
+| ALL | United States | 1999 | 1700 |
+| ALL | United States | 2000 | 3300 |
+| Calculator | ALL | 1999 | 50 |
+| Calculator | ALL | 2000 | 225 |
+| Computer | ALL | 1999 | 2700 |
+| Computer | ALL | 2000 | 4200 |
+| TV | ALL | 1999 | 250 |
+| TV | ALL | 2000 | 350 |
+| Calculator | India | ALL | 75 |
+| Calculator | United States | ALL | 200 |
+| Computer | India | ALL | 2400 |
+| Computer | United States | ALL | 4500 |
+| TV | India | ALL | 300 |
+| TV | United States | ALL | 300 |
+| ALL | ALL | 1999 | 3000 |
+| ALL | ALL | 2000 | 4775 |
+| ALL | India | ALL | 2775 |
+| ALL | United States | ALL | 5000 |
+| Calculator | ALL | ALL | 275 |
+| Computer | ALL | ALL | 6900 |
+| TV | ALL | ALL | 600 |
+| ALL | ALL | ALL | 7775 |
++------------+---------------+------+-------------+
+35 rows in set (0.00 sec)
+
+
+MySQL supports now CUBE and ROLLUP extensions, with all functions
+that one wishes to use with them.
+
+Those extensions already work in all tested combinations. They work
+with UNION's, should work with sub-selects in 4.1 and derived tables.
+
+TODO
+----
+
+For the moment, ORDER and LIMIT are disabled for CUBE and ROLLUP. This
+however remains to be added later.
+
+Another feature that has to be added later is grouping of select list
+itmes in order to alleviate user errors. For the moment, missing
+(hidden) columns are not used at all.
+-------------------------------------------------------------------------
+
@node News-4.0.2, News-4.0.1, News-4.0.3, News-4.0.x
@appendixsubsec Changes in release 4.0.2 (01 July 2002)
diff --git a/mysql-test/r/olap.result b/mysql-test/r/olap.result
new file mode 100644
index 00000000000..0842b038235
--- /dev/null
+++ b/mysql-test/r/olap.result
@@ -0,0 +1,138 @@
+drop table if exists sales;
+create table sales ( product varchar(32), country varchar(32), year int, profit int);
+insert into sales values ( 'Computer', 'India',2000, 1200),
+( 'TV', 'United States', 1999, 150),
+( 'Calculator', 'United States', 1999,50),
+( 'Computer', 'United States', 1999,1500),
+( 'Computer', 'United States', 2000,1500),
+( 'TV', 'United States', 2000, 150),
+( 'TV', 'India', 2000, 100),
+( 'TV', 'India', 2000, 100),
+( 'Calculator', 'United States', 2000,75),
+( 'Calculator', 'India', 2000,75),
+( 'TV', 'India', 1999, 100),
+( 'Computer', 'India', 1999,1200),
+( 'Computer', 'United States', 2000,1500),
+( 'Calculator', 'United States', 2000,75);
+select product, country , year, sum(profit) from sales group by product, country, year with cube;
+product country year sum(profit)
+Calculator India 2000 75
+Calculator United States 1999 50
+Calculator United States 2000 150
+Computer India 1999 1200
+Computer India 2000 1200
+Computer United States 1999 1500
+Computer United States 2000 3000
+TV India 1999 100
+TV India 2000 200
+TV United States 1999 150
+TV United States 2000 150
+Calculator India 0 75
+Calculator United States 0 200
+Computer India 0 2400
+Computer United States 0 4500
+TV India 0 300
+TV United States 0 300
+Calculator ALL 1999 50
+Calculator ALL 2000 225
+Computer ALL 1999 2700
+Computer ALL 2000 4200
+TV ALL 1999 250
+TV ALL 2000 350
+ALL India 1999 1300
+ALL India 2000 1475
+ALL United States 1999 1700
+ALL United States 2000 3300
+Calculator ALL 0 275
+Computer ALL 0 6900
+TV ALL 0 600
+ALL India 0 2775
+ALL United States 0 5000
+ALL ALL 1999 3000
+ALL ALL 2000 4775
+ALL ALL 0 7775
+explain select product, country , year, sum(profit) from sales group by product, country, year with cube;
+table type possible_keys key key_len ref rows Extra
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14
+select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+product country year sum(profit)
+Calculator India 2000 75
+Calculator United States 1999 50
+Calculator United States 2000 150
+Computer India 1999 1200
+Computer India 2000 1200
+Computer United States 1999 1500
+Computer United States 2000 3000
+TV India 1999 100
+TV India 2000 200
+TV United States 1999 150
+TV United States 2000 150
+ALL India 1999 1300
+ALL India 2000 1475
+ALL United States 1999 1700
+ALL United States 2000 3300
+ALL ALL 1999 3000
+ALL ALL 2000 4775
+ALL ALL 0 7775
+explain select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+table type possible_keys key key_len ref rows Extra
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14 Using temporary; Using filesort
+sales ALL NULL NULL NULL NULL 14
+select product, country , year, sum(profit) from sales group by product, country, year with cube union all select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+product country year sum(profit)
+Calculator India 2000 75
+Calculator United States 1999 50
+Calculator United States 2000 150
+Computer India 1999 1200
+Computer India 2000 1200
+Computer United States 1999 1500
+Computer United States 2000 3000
+TV India 1999 100
+TV India 2000 200
+TV United States 1999 150
+TV United States 2000 150
+Calculator India 0 75
+Calculator United States 0 200
+Computer India 0 2400
+Computer United States 0 4500
+TV India 0 300
+TV United States 0 300
+Calculator ALL 1999 50
+Calculator ALL 2000 225
+Computer ALL 1999 2700
+Computer ALL 2000 4200
+TV ALL 1999 250
+TV ALL 2000 350
+ALL India 1999 1300
+ALL India 2000 1475
+ALL United States 1999 1700
+ALL United States 2000 3300
+Calculator ALL 0 275
+Computer ALL 0 6900
+TV ALL 0 600
+ALL India 0 2775
+ALL United States 0 5000
+ALL ALL 1999 3000
+ALL ALL 2000 4775
+ALL ALL 0 7775
+Calculator India 2000 75
+Calculator United States 1999 50
+Calculator United States 2000 150
+Computer India 1999 1200
+Computer India 2000 1200
+Computer United States 1999 1500
+Computer United States 2000 3000
+TV India 1999 100
+TV India 2000 200
+TV United States 1999 150
+TV United States 2000 150
+drop table sales;
diff --git a/mysql-test/t/olap.test b/mysql-test/t/olap.test
new file mode 100644
index 00000000000..b91bf2fb193
--- /dev/null
+++ b/mysql-test/t/olap.test
@@ -0,0 +1,22 @@
+drop table if exists sales;
+create table sales ( product varchar(32), country varchar(32), year int, profit int);
+insert into sales values ( 'Computer', 'India',2000, 1200),
+( 'TV', 'United States', 1999, 150),
+( 'Calculator', 'United States', 1999,50),
+( 'Computer', 'United States', 1999,1500),
+( 'Computer', 'United States', 2000,1500),
+( 'TV', 'United States', 2000, 150),
+( 'TV', 'India', 2000, 100),
+( 'TV', 'India', 2000, 100),
+( 'Calculator', 'United States', 2000,75),
+( 'Calculator', 'India', 2000,75),
+( 'TV', 'India', 1999, 100),
+( 'Computer', 'India', 1999,1200),
+( 'Computer', 'United States', 2000,1500),
+( 'Calculator', 'United States', 2000,75);
+select product, country , year, sum(profit) from sales group by product, country, year with cube;
+explain select product, country , year, sum(profit) from sales group by product, country, year with cube;
+select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+explain select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+select product, country , year, sum(profit) from sales group by product, country, year with cube union all select product, country , year, sum(profit) from sales group by product, country, year with rollup;
+drop table sales;
diff --git a/sql/item.h b/sql/item.h
index 7612246b4b0..d4f2ba412a8 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -82,6 +82,7 @@ public:
virtual bool get_date(TIME *ltime,bool fuzzydate);
virtual bool get_time(TIME *ltime);
virtual bool is_null() { return 0; }
+ virtual unsigned int size_of () =0;
};
@@ -96,6 +97,7 @@ public:
:db_name(db_name_par),table_name(table_name_par),field_name(field_name_par)
{ name = (char*) field_name_par; }
const char *full_name() const;
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_field :public Item_ident
@@ -135,6 +137,7 @@ public:
bool get_date(TIME *ltime,bool fuzzydate);
bool get_time(TIME *ltime);
bool is_null() { return field->is_null(); }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -156,6 +159,7 @@ public:
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); }
bool is_null() { return 1; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -185,6 +189,7 @@ public:
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_int(name,value,max_length); }
void print(String *str);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -198,6 +203,7 @@ public:
void make_field(Send_field *field);
Item *new_item() { return new Item_uint(name,max_length); }
void print(String *str);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -228,6 +234,7 @@ public:
void make_field(Send_field *field);
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_real(name,value,decimals,max_length); }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -239,6 +246,7 @@ public:
decimals=NOT_FIXED_DEC;
max_length=DBL_DIG+8;
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_string :public Item
@@ -272,6 +280,7 @@ public:
String *const_string() { return &str_value; }
inline void append(char *str,uint length) { str_value.append(str,length); }
void print(String *str);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
/* for show tables */
@@ -282,6 +291,7 @@ public:
Item_datetime(const char *item_name): Item_string(item_name,"",0)
{ max_length=19;}
void make_field(Send_field *field);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_empty_string :public Item_string
@@ -289,6 +299,7 @@ class Item_empty_string :public Item_string
public:
Item_empty_string(const char *header,uint length) :Item_string("",0)
{ name=(char*) header; max_length=length;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_varbinary :public Item
@@ -303,6 +314,7 @@ public:
bool save_in_field(Field *field);
void make_field(Send_field *field);
enum Item_result result_type () const { return INT_RESULT; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -315,6 +327,7 @@ public:
Field *tmp_table_field(TABLE *t_arg=(TABLE *)0) { return result_field; }
table_map used_tables() const { return 1; }
virtual void fix_length_and_dec()=0;
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -364,6 +377,7 @@ public:
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); }
table_map used_tables() const { return (*ref)->used_tables(); }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -383,6 +397,7 @@ public:
{
return ref->save_in_field(field);
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -417,6 +432,7 @@ public:
table_map used_tables() const { return (table_map) 1L; }
bool const_item() const { return 0; }
bool is_null() { return null_value; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -427,6 +443,7 @@ public:
Item_buff() :null_value(0) {}
virtual bool cmp(void)=0;
virtual ~Item_buff(); /*line -e1509 */
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_str_buff :public Item_buff
@@ -437,6 +454,7 @@ public:
Item_str_buff(Item *arg) :item(arg),value(arg->max_length) {}
bool cmp(void);
~Item_str_buff(); // Deallocate String:s
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -447,6 +465,7 @@ class Item_real_buff :public Item_buff
public:
Item_real_buff(Item *item_par) :item(item_par),value(0.0) {}
bool cmp(void);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_int_buff :public Item_buff
@@ -456,6 +475,7 @@ class Item_int_buff :public Item_buff
public:
Item_int_buff(Item *item_par) :item(item_par),value(0) {}
bool cmp(void);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -472,6 +492,7 @@ public:
buff= (char*) sql_calloc(length=field->pack_length());
}
bool cmp(void);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
extern Item_buff *new_Item_buff(Item *item);
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 25d0c239647..8cda0302af5 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -28,6 +28,7 @@ public:
Item_bool_func(Item *a) :Item_int_func(a) {}
Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {}
void fix_length_and_dec() { decimals=0; max_length=1; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_bool_func2 :public Item_int_func
@@ -47,6 +48,7 @@ public:
bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; }
void print(String *str) { Item_func::print_op(str); }
bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -80,6 +82,7 @@ public:
enum Functype rev_functype() const { return EQUAL_FUNC; }
cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "<=>"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -185,6 +188,7 @@ public:
~Item_func_interval() { delete item; }
const char *func_name() const { return "interval"; }
void update_used_tables();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -199,6 +203,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "ifnull"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -213,6 +218,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "if"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -227,6 +233,7 @@ public:
enum Item_result result_type () const { return cached_result_type; }
void fix_length_and_dec();
const char *func_name() const { return "nullif"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -241,6 +248,7 @@ public:
void fix_length_and_dec();
enum Item_result result_type () const { return cached_result_type; }
const char *func_name() const { return "coalesce"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_case :public Item_func
@@ -261,6 +269,7 @@ public:
void print(String *str);
bool fix_fields(THD *thd,struct st_table_list *tlist);
Item *find_item(String *str);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -422,6 +431,7 @@ class Item_func_in :public Item_int_func
enum Functype functype() const { return IN_FUNC; }
const char *func_name() const { return " IN "; }
void update_used_tables();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -459,6 +469,7 @@ public:
}
}
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_isnotnull :public Item_bool_func
@@ -473,6 +484,7 @@ public:
}
const char *func_name() const { return "isnotnull"; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_like :public Item_bool_func2
@@ -506,6 +518,7 @@ public:
const char *func_name() const { return "like"; }
void fix_length_and_dec();
bool fix_fields(THD *thd,struct st_table_list *tlist);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
#ifdef USE_REGEX
@@ -525,6 +538,7 @@ public:
longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist);
const char *func_name() const { return "regex"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
#else
@@ -561,6 +575,7 @@ public:
void print(String *str);
void split_sum_func(List<Item> &fields);
friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
diff --git a/sql/item_func.h b/sql/item_func.h
index 5560d3cdb0d..6ecbc04ddf0 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -121,6 +121,7 @@ public:
}
bool is_null() { (void) val_int(); return null_value; }
friend class udf_handler;
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -140,6 +141,7 @@ public:
if (!t_arg) return result_field;
return new Field_double(max_length, maybe_null, name,t_arg,decimals);
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_num_func :public Item_func
@@ -154,6 +156,7 @@ public:
enum Item_result result_type () const { return hybrid_type; }
void fix_length_and_dec() { fix_num_length_and_dec(); }
bool is_null() { (void) val(); return null_value; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -187,6 +190,7 @@ class Item_num_op :public Item_func
res= new Field_double(max_length, maybe_null, name, t_arg, decimals);
return res;
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -459,6 +463,7 @@ public:
const char *func_name() const { return truncate ? "truncate" : "round"; }
double val();
void fix_length_and_dec();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -494,6 +499,7 @@ class Item_func_units :public Item_real_func
double val();
const char *func_name() const { return name; }
void fix_length_and_dec() { decimals=NOT_FIXED_DEC; max_length=float_length(decimals); }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -510,6 +516,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
enum Item_result result_type () const { return cmp_type; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_min :public Item_func_min_max
@@ -535,6 +542,7 @@ public:
longlong val_int();
const char *func_name() const { return "length"; }
void fix_length_and_dec() { max_length=10; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_bit_length :public Item_func_length
@@ -553,6 +561,7 @@ public:
longlong val_int();
const char *func_name() const { return "char_length"; }
void fix_length_and_dec() { max_length=10; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_locate :public Item_int_func
@@ -564,6 +573,7 @@ public:
const char *func_name() const { return "locate"; }
longlong val_int();
void fix_length_and_dec() { maybe_null=0; max_length=11; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -593,6 +603,7 @@ public:
const_item_cache&= item->const_item();
with_sum_func= with_sum_func || item->with_sum_func;
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -604,6 +615,7 @@ public:
longlong val_int();
const char *func_name() const { return "ascii"; }
void fix_length_and_dec() { max_length=3; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_ord :public Item_int_func
@@ -613,6 +625,7 @@ public:
Item_func_ord(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "ord"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_find_in_set :public Item_int_func
@@ -625,6 +638,7 @@ public:
longlong val_int();
const char *func_name() const { return "find_in_set"; }
void fix_length_and_dec();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -700,6 +714,7 @@ class Item_func_benchmark :public Item_int_func
longlong val_int();
const char *func_name() const { return "benchmark"; }
void fix_length_and_dec() { max_length=1; maybe_null=0; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -724,6 +739,7 @@ public:
return res;
}
Item_result result_type () const { return udf.result_type(); }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -832,6 +848,7 @@ class Item_func_get_lock :public Item_int_func
longlong val_int();
const char *func_name() const { return "get_lock"; }
void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_release_lock :public Item_int_func
@@ -842,6 +859,7 @@ class Item_func_release_lock :public Item_int_func
longlong val_int();
const char *func_name() const { return "release_lock"; }
void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
/* replication functions */
@@ -854,6 +872,7 @@ class Item_master_pos_wait :public Item_int_func
longlong val_int();
const char *func_name() const { return "master_pos_wait"; }
void fix_length_and_dec() { max_length=1; maybe_null=1;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -879,6 +898,7 @@ public:
void fix_length_and_dec();
void print(String *str);
const char *func_name() const { return "set_user_var"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -903,6 +923,7 @@ public:
table_map used_tables() const
{ return const_var_flag ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -958,6 +979,7 @@ public:
bool fix_index();
void init_search(bool no_order);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -1008,4 +1030,5 @@ public:
longlong val_int();
const char *func_name() const { return "check_lock"; }
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 85910f45c77..efff9d93941 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -40,6 +40,7 @@ public:
if (!t_arg) return result_field;
return (max_length > 255) ? (Field *)new Field_blob(max_length,maybe_null, name,t_arg, binary) : (Field *) new Field_string(max_length,maybe_null, name,t_arg, binary);
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_md5 :public Item_str_func
@@ -50,6 +51,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "md5"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_sha :public Item_str_func
@@ -89,6 +91,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "concat"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_concat_ws :public Item_str_func
@@ -109,6 +112,7 @@ public:
|| Item_func::fix_fields(thd,tlist));
}
const char *func_name() const { return "concat_ws"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_reverse :public Item_str_func
@@ -129,6 +133,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "replace"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -141,6 +146,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "insert"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -187,6 +193,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "right"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -199,6 +206,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "substr"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -210,6 +218,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "substr_index"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -221,6 +230,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "ltrim"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -232,6 +242,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "rtrim"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_trim :public Item_str_func
@@ -242,6 +253,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length= args[0]->max_length; }
const char *func_name() const { return "trim"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -253,6 +265,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { max_length = 16; }
const char *func_name() const { return "password"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_des_encrypt :public Item_str_func
@@ -265,6 +278,7 @@ public:
void fix_length_and_dec()
{ maybe_null=1; max_length = args[0]->max_length+8; }
const char *func_name() const { return "des_encrypt"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_des_decrypt :public Item_str_func
@@ -276,6 +290,7 @@ public:
String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; }
const char *func_name() const { return "des_decrypt"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_encrypt :public Item_str_func
@@ -286,6 +301,7 @@ public:
Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
String *val_str(String *);
void fix_length_and_dec() { maybe_null=1; max_length = 13; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
#include "sql_crypt.h"
@@ -299,6 +315,7 @@ public:
Item_str_func(a),sql_crypt(seed) {}
String *val_str(String *);
void fix_length_and_dec();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_decode :public Item_func_encode
@@ -336,6 +353,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "soundex"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -356,6 +374,7 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "elt"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -375,6 +394,7 @@ public:
void fix_length_and_dec();
void update_used_tables();
const char *func_name() const { return "make_set"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -389,6 +409,7 @@ public:
max_length=args[0]->max_length+(args[0]->max_length-args[0]->decimals)/3;
}
const char *func_name() const { return "format"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -410,6 +431,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "repeat"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -422,6 +444,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "rpad"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -434,6 +457,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "lpad"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -455,6 +479,7 @@ public:
const char *func_name() const { return "hex"; }
String *val_str(String *);
void fix_length_and_dec() { decimals=0; max_length=args[0]->max_length*2; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -479,6 +504,7 @@ public:
const char *func_name() const { return "load_file"; }
void fix_length_and_dec()
{ binary=1; maybe_null=1; max_length=MAX_BLOB_WIDTH;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
diff --git a/sql/item_sum.h b/sql/item_sum.h
index a963799b6a7..8326114629b 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -70,6 +70,7 @@ public:
void print(String *str);
void fix_num_length_and_dec();
virtual bool setup(THD *thd) {return 0;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -84,6 +85,7 @@ public:
longlong val_int() { return (longlong) val(); } /* Real as default */
String *val_str(String*str);
void reset_field();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -98,6 +100,7 @@ public:
double val() { return (double) val_int(); }
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -115,6 +118,7 @@ class Item_sum_sum :public Item_sum_num
void reset_field();
void update_field(int offset);
const char *func_name() const { return "sum"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -137,6 +141,7 @@ class Item_sum_count :public Item_sum_int
void reset_field();
void update_field(int offset);
const char *func_name() const { return "count"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -188,6 +193,7 @@ class Item_sum_count_distinct :public Item_sum_int
void update_field(int offset) { return ; } // Never called
const char *func_name() const { return "count_distinct"; }
bool setup(THD *thd);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -207,6 +213,7 @@ public:
String *val_str(String*);
void make_field(Send_field *field);
void fix_length_and_dec() {}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -228,6 +235,7 @@ class Item_sum_avg :public Item_sum_num
Item *result_item(Field *field)
{ return new Item_avg_field(this); }
const char *func_name() const { return "avg"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_sum_std;
@@ -244,6 +252,7 @@ public:
bool is_null() { (void) val_int(); return null_value; }
void make_field(Send_field *field);
void fix_length_and_dec() {}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_sum_std :public Item_sum_num
@@ -264,6 +273,7 @@ class Item_sum_std :public Item_sum_num
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -306,6 +316,7 @@ class Item_sum_hybrid :public Item_sum
void min_max_update_str_field(int offset);
void min_max_update_real_field(int offset);
void min_max_update_int_field(int offset);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -317,6 +328,7 @@ public:
bool add();
const char *func_name() const { return "min"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -328,6 +340,7 @@ public:
bool add();
const char *func_name() const { return "max"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -343,6 +356,7 @@ class Item_sum_bit :public Item_sum_int
void reset();
longlong val_int();
void reset_field();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -353,6 +367,7 @@ class Item_sum_or :public Item_sum_bit
bool add();
void update_field(int offset);
const char *func_name() const { return "bit_or"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -363,6 +378,7 @@ class Item_sum_and :public Item_sum_bit
bool add();
void update_field(int offset);
const char *func_name() const { return "bit_and"; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
/*
@@ -393,6 +409,7 @@ public:
bool add();
void reset_field() {};
void update_field(int offset_arg) {};
+ virtual unsigned int size_of () { return sizeof(*this);}
};
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index cc5902b4920..08fbfe25093 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -175,6 +175,7 @@ public:
const char *func_name() const { return "weekday"; }
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=1; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_func_dayname :public Item_func_weekday
@@ -200,6 +201,7 @@ public:
{
decimals=0; max_length=10;
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -238,6 +240,7 @@ public:
if (!t_arg) return result_field;
return new Field_date(maybe_null, name, t_arg);
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -256,6 +259,7 @@ public:
if (!t_arg) return result_field;
return new Field_datetime(maybe_null, name, t_arg);
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -283,6 +287,7 @@ public:
if (!t_arg) return result_field;
return new Field_time(maybe_null, name, t_arg);
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -296,6 +301,7 @@ public:
const char *func_name() const { return "curdate"; }
void fix_length_and_dec(); /* Retrieves curtime */
bool get_date(TIME *res,bool fuzzy_date);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -317,6 +323,7 @@ public:
const char *func_name() const { return "now"; }
void fix_length_and_dec();
bool get_date(TIME *res,bool fuzzy_date);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -341,6 +348,7 @@ public:
const char *func_name() const { return "date_format"; }
void fix_length_and_dec();
uint format_length(const String *format);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -400,6 +408,7 @@ public:
double val() { return (double) val_int(); }
longlong val_int();
bool get_date(TIME *res,bool fuzzy_date);
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_extract :public Item_int_func
@@ -413,6 +422,7 @@ class Item_extract :public Item_int_func
longlong val_int();
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_typecast :public Item_str_func
diff --git a/sql/item_uniq.h b/sql/item_uniq.h
index 4be64ecc74a..18f5e5ca45e 100644
--- a/sql/item_uniq.h
+++ b/sql/item_uniq.h
@@ -29,6 +29,7 @@ public:
:Item_real_func(list) {}
double val() { return 0.0; }
void fix_length_and_dec() { decimals=0; max_length=6; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_sum_unique_users :public Item_sum_num
@@ -43,4 +44,5 @@ public:
void reset_field() {}
void update_field(int offset) {}
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
diff --git a/sql/lex.h b/sql/lex.h
index c44cef05215..4f5d3c794ff 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -98,7 +98,7 @@ static SYMBOL symbols[] = {
{ "CONSTRAINT", SYM(CONSTRAINT),0,0},
{ "CREATE", SYM(CREATE),0,0},
{ "CROSS", SYM(CROSS),0,0},
- { "CUBE", SYM(CUBE),0,0},
+ { "CUBE", SYM(CUBE_SYM),0,0},
{ "CURRENT_DATE", SYM(CURDATE),0,0},
{ "CURRENT_TIME", SYM(CURTIME),0,0},
{ "CURRENT_TIMESTAMP", SYM(NOW_SYM),0,0},
@@ -304,7 +304,7 @@ static SYMBOL symbols[] = {
{ "RIGHT", SYM(RIGHT),0,0},
{ "RLIKE", SYM(REGEXP),0,0}, /* Like in mSQL2 */
{ "ROLLBACK", SYM(ROLLBACK_SYM),0,0},
- { "ROLLUP", SYM(ROLLUP),0,0},
+ { "ROLLUP", SYM(ROLLUP_SYM),0,0},
{ "ROW", SYM(ROW_SYM),0,0},
{ "ROWS", SYM(ROWS_SYM),0,0},
{ "SECOND", SYM(SECOND_SYM),0,0},
diff --git a/sql/procedure.h b/sql/procedure.h
index db0e0b7f9e2..d2600a62e62 100644
--- a/sql/procedure.h
+++ b/sql/procedure.h
@@ -43,6 +43,7 @@ public:
{
init_make_field(tmp_field,field_type());
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_proc_real :public Item_proc
@@ -62,6 +63,7 @@ public:
double val() { return value; }
longlong val_int() { return (longlong) value; }
String *val_str(String *s) { s->set(value,decimals); return s; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
class Item_proc_int :public Item_proc
@@ -79,6 +81,7 @@ public:
double val() { return (double) value; }
longlong val_int() { return value; }
String *val_str(String *s) { s->set(value); return s; }
+ virtual unsigned int size_of () { return sizeof(*this);}
};
@@ -98,6 +101,7 @@ public:
{
return null_value ? (String*) 0 : (String*) &str_value;
}
+ virtual unsigned int size_of () { return sizeof(*this);}
};
/* The procedure class definitions */
diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc
new file mode 100644
index 00000000000..a18fbd24efd
--- /dev/null
+++ b/sql/sql_olap.cc
@@ -0,0 +1,181 @@
+/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/* OLAP implementation by Sinisa Milivojevic <sinisa@mysql.com*/
+
+#ifdef __GNUC__
+#pragma implementation // gcc: Class implementation
+#endif
+
+#include "mysql_priv.h"
+#include "sql_select.h"
+
+
+/****************************************************************************
+ Functions that recursively actually creates new SELECT's
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+
+static int make_new_olap_select(LEX *lex, SELECT_LEX *select_lex, List<Item> new_fields)
+{
+ THD *thd=current_thd;
+ Item *item, *new_item;
+ Item_string *constant= new Item_string("ALL",3);
+
+ SELECT_LEX *new_select = (SELECT_LEX *) thd->memdup((char*) select_lex, sizeof(*select_lex));
+ if (!new_select)
+ return 1;
+ lex->last_selects->next=new_select;
+ new_select->linkage=OLAP_TYPE;
+ new_select->olap=NON_EXISTING_ONE;
+ new_select->group_list.elements=0;
+ new_select->group_list.first=(byte *)0;
+ new_select->group_list.next=(byte **)&new_select->group_list.first;
+ List<Item> privlist;
+
+ List_iterator<Item> list_it(select_lex->item_list);
+ List_iterator<Item> new_it(new_fields);
+
+ while((item=list_it++))
+ {
+ bool not_found=true;
+ if (item->type()==Item::FIELD_ITEM)
+ {
+ Item_field *iif = (Item_field *)item;
+ new_it.rewind();
+ while ((new_item=new_it++))
+ {
+ if (new_item->type()==Item::FIELD_ITEM &&
+ !strcmp(((Item_field*)new_item)->table_name,iif->table_name) &&
+ !strcmp(((Item_field*)new_item)->field_name,iif->field_name))
+ {
+ not_found=false;
+ ((Item_field*)new_item)->db_name=iif->db_name;
+ Item_field *new_one=new Item_field(iif->db_name, iif->table_name, iif->field_name);
+ privlist.push_back(new_one);
+ if (add_to_list(new_select->group_list,new_one,1))
+ return 1;
+ break;
+ }
+ }
+ }
+ if (not_found)
+ {
+ if (item->type() == Item::FIELD_ITEM)
+ privlist.push_back(constant);
+ else
+ privlist.push_back((Item*)thd->memdup((char *)item,item->size_of()));
+ }
+ }
+ new_select->item_list=privlist;
+
+ lex->last_selects = new_select;
+ return 0;
+}
+
+/****************************************************************************
+ Functions that recursively creates combinations of queries for OLAP
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+static int olap_combos(List<Item> old_fields, List<Item> new_fields, Item *item, LEX *lex,
+ SELECT_LEX *select_lex, int position, int selection, int num_fields,
+ int num_new_fields)
+{
+ int sl_return = 0;
+ if(position == num_new_fields)
+ {
+ if(item)
+ new_fields.push_front(item);
+ sl_return = make_new_olap_select(lex, select_lex, new_fields);
+ }
+ else
+ {
+ if(item)
+ new_fields.push_front(item);
+ while ((num_fields - num_new_fields >= selection - position) && !sl_return)
+ {
+ item = old_fields.pop();
+ sl_return = olap_combos(old_fields, new_fields, item, lex, select_lex, position+1, ++selection, num_fields, num_new_fields);
+ }
+ }
+ return sl_return;
+}
+
+
+/****************************************************************************
+ Top level function for converting OLAP clauses to multiple selects
+ This is also a place where clauses treatment depends on OLAP type
+ Returns 0 if OK, 1 if error, -1 if error already printed to client
+****************************************************************************/
+
+int handle_olaps(LEX *lex, SELECT_LEX *select_lex)
+{
+ List<Item> item_list_copy, new_item_list;
+ item_list_copy.empty();
+ new_item_list.empty();
+ int count=select_lex->group_list.elements;
+ int sl_return=0;
+
+// a fix for UNION's
+ for (TABLE_LIST *cursor= (TABLE_LIST *)select_lex->table_list.first;
+ cursor;
+ cursor=cursor->next)
+ {
+ if (cursor->do_redirect)
+ {
+ cursor->table= ((TABLE_LIST*) cursor->table)->table;
+ cursor->do_redirect=false;
+ }
+ }
+
+ lex->last_selects=select_lex;
+
+ for (ORDER *order=(ORDER *)select_lex->group_list.first ; order ; order=order->next)
+ item_list_copy.push_back(*(order->item));
+
+ List<Item> all_fields(select_lex->item_list);
+
+
+ if (setup_tables((TABLE_LIST *)select_lex->table_list.first) ||
+ setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,select_lex->item_list,1,&all_fields,1) ||
+ setup_fields(lex->thd,(TABLE_LIST *)select_lex->table_list.first,item_list_copy,1,&all_fields,1))
+ return -1;
+
+ if (select_lex->olap == CUBE_TYPE)
+ {
+ for( int i=count-1; i>=0 && !sl_return; i--)
+ sl_return=olap_combos(item_list_copy, new_item_list, (Item *)0, lex, select_lex, 0, 0, count, i);
+ }
+ else if (select_lex->olap == ROLLUP_TYPE)
+ {
+ for( int i=count-1; i>=0 && !sl_return; i--)
+ {
+ Item *item;
+ item_list_copy.pop();
+ List_iterator<Item> it(item_list_copy);
+ new_item_list.empty();
+ while ((item = it++))
+ new_item_list.push_front(item);
+ sl_return=make_new_olap_select(lex, select_lex, new_item_list);
+ }
+ }
+ else
+ sl_return=1; // impossible
+ return sl_return;
+}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 558e1e6d1fd..5d085abd40b 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2714,6 +2714,7 @@ mysql_init_query(THD *thd)
thd->lex.select_lex.table_list.first=0;
thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first;
thd->lex.select_lex.next=0;
+ thd->lex.olap=0;
thd->fatal_error=0; // Safety
thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
thd->sent_row_count=thd->examined_row_count=0;
@@ -2732,7 +2733,6 @@ mysql_init_select(LEX *lex)
select_lex->linkage=UNSPECIFIED_TYPE;
select_lex->olap= NON_EXISTING_ONE;
lex->exchange = 0;
- lex->olap = 0;
lex->proc_list.first=0;
select_lex->order_list.elements=select_lex->group_list.elements=0;
select_lex->order_list.first=0;
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index f25a6e57315..fbfafd41420 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -258,6 +258,7 @@ bool select_union::send_data(List<Item> &values)
thd->offset_limit--;
return 0;
}
+
fill_record(table->field,values);
if ((write_record(table,&info)))
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index b2213c29fdf..ced5a28b4f0 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -109,7 +109,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token COUNT_SYM
%token CREATE
%token CROSS
-%token CUBE
+%token CUBE_SYM
%token DELETE_SYM
%token DO_SYM
%token DROP
@@ -131,7 +131,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token REPLICATION
%token RESET_SYM
%token ROLLBACK_SYM
-%token ROLLUP
+%token ROLLUP_SYM
%token SELECT_SYM
%token SHOW
%token SLAVE
@@ -2172,12 +2172,12 @@ group_list:
olap_opt:
/* empty */ {}
- | WITH CUBE
+ | WITH CUBE_SYM
{
Lex->olap = true;
Select->olap= CUBE_TYPE;
}
- | WITH ROLLUP
+ | WITH ROLLUP_SYM
{
Lex->olap = true;
Select->olap= ROLLUP_TYPE;
@@ -2195,8 +2195,10 @@ order_clause:
ORDER_SYM BY
{
LEX *lex=Lex;
- if (lex->sql_command == SQLCOM_MULTI_UPDATE || lex->olap)
+ if (lex->sql_command == SQLCOM_MULTI_UPDATE)
YYABORT;
+ if (lex->olap)
+ YYABORT;
lex->select->sort_default=1;
} order_list;
@@ -2216,7 +2218,8 @@ limit_clause:
/* empty */ {}
| LIMIT ULONG_NUM
{
- if (Lex->olap)
+ LEX *lex=Lex;
+ if (lex->olap)
YYABORT;
SELECT_LEX *sel=Select;
sel->select_limit= $2;
@@ -2224,7 +2227,8 @@ limit_clause:
}
| LIMIT ULONG_NUM ',' ULONG_NUM
{
- if (Lex->olap)
+ LEX *lex=Lex;
+ if (lex->olap)
YYABORT;
SELECT_LEX *sel=Select;
sel->select_limit= $4; sel->offset_limit=$2;
@@ -3043,7 +3047,7 @@ keyword:
| COMMIT_SYM {}
| COMPRESSED_SYM {}
| CONCURRENT {}
- | CUBE {}
+ | CUBE_SYM {}
| DATA_SYM {}
| DATETIME {}
| DATE_SYM {}
@@ -3137,7 +3141,7 @@ keyword:
| RESOURCES {}
| RESTORE_SYM {}
| ROLLBACK_SYM {}
- | ROLLUP {}
+ | ROLLUP_SYM {}
| ROWS_SYM {}
| ROW_FORMAT_SYM {}
| ROW_SYM {}