diff options
-rw-r--r-- | Docs/manual.texi | 136 | ||||
-rw-r--r-- | mysql-test/r/olap.result | 138 | ||||
-rw-r--r-- | mysql-test/t/olap.test | 22 | ||||
-rw-r--r-- | sql/item.h | 21 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 15 | ||||
-rw-r--r-- | sql/item_func.h | 23 | ||||
-rw-r--r-- | sql/item_strfunc.h | 26 | ||||
-rw-r--r-- | sql/item_sum.h | 17 | ||||
-rw-r--r-- | sql/item_timefunc.h | 10 | ||||
-rw-r--r-- | sql/item_uniq.h | 2 | ||||
-rw-r--r-- | sql/lex.h | 4 | ||||
-rw-r--r-- | sql/procedure.h | 4 | ||||
-rw-r--r-- | sql/sql_olap.cc | 181 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_union.cc | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 22 |
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 {} |