OLAP functionality plus some small bug fixes

parent 4331c705
......@@ -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)
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;
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;
......@@ -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);
......
......@@ -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);}
};
......
......@@ -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);}
};
......@@ -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);}
};
......
......@@ -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);}
};
......
......@@ -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
......
......@@ -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);}
};
......@@ -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},
......
......@@ -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 */
......
/* 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;
}
......@@ -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;
......
......@@ -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)))
{
......
......@@ -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 {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment