mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
Initial patch for the implementation of window functions (MDEV-6115):
- All parsing problems look like resolved - Stub performing name resolution of window functions in simplest queries has been added.
This commit is contained in:
parent
2cfc450bf7
commit
9d9c60fb12
15 changed files with 768 additions and 6 deletions
|
@ -109,6 +109,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
|
||||||
../sql/table_cache.cc ../sql/mf_iocache_encr.cc
|
../sql/table_cache.cc ../sql/mf_iocache_encr.cc
|
||||||
../sql/item_inetfunc.cc
|
../sql/item_inetfunc.cc
|
||||||
../sql/wsrep_dummy.cc ../sql/encryption.cc
|
../sql/wsrep_dummy.cc ../sql/encryption.cc
|
||||||
|
../sql/item_windowfunc.cc ../sql/sql_window.cc
|
||||||
${GEN_SOURCES}
|
${GEN_SOURCES}
|
||||||
${MYSYS_LIBWRAP_SOURCE}
|
${MYSYS_LIBWRAP_SOURCE}
|
||||||
)
|
)
|
||||||
|
|
|
@ -122,7 +122,7 @@ SET (SQL_SOURCE
|
||||||
sql_profile.cc event_parse_data.cc sql_alter.cc
|
sql_profile.cc event_parse_data.cc sql_alter.cc
|
||||||
sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc
|
sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc
|
||||||
transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
|
transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
|
||||||
sql_reload.cc sql_cmd.h item_inetfunc.cc
|
sql_reload.cc sql_cmd.h item_inetfunc.cc
|
||||||
|
|
||||||
# added in MariaDB:
|
# added in MariaDB:
|
||||||
sql_explain.h sql_explain.cc
|
sql_explain.h sql_explain.cc
|
||||||
|
@ -137,6 +137,7 @@ SET (SQL_SOURCE
|
||||||
my_json_writer.cc my_json_writer.h
|
my_json_writer.cc my_json_writer.h
|
||||||
rpl_gtid.cc rpl_parallel.cc
|
rpl_gtid.cc rpl_parallel.cc
|
||||||
sql_type.cc sql_type.h
|
sql_type.cc sql_type.h
|
||||||
|
item_windowfunc.cc sql_window.cc
|
||||||
${WSREP_SOURCES}
|
${WSREP_SOURCES}
|
||||||
table_cache.cc encryption.cc
|
table_cache.cc encryption.cc
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc
|
${CMAKE_CURRENT_BINARY_DIR}/sql_builtin.cc
|
||||||
|
|
|
@ -628,7 +628,8 @@ public:
|
||||||
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
|
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
|
||||||
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
|
||||||
|
|
||||||
enum Type {FIELD_ITEM= 0, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM,
|
enum Type {FIELD_ITEM= 0, FUNC_ITEM, SUM_FUNC_ITEM,
|
||||||
|
WINDOW_FUNC_ITEM, STRING_ITEM,
|
||||||
INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
|
INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM,
|
||||||
COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
|
COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
|
||||||
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
|
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
|
||||||
|
|
|
@ -347,7 +347,9 @@ public:
|
||||||
enum Sumfunctype
|
enum Sumfunctype
|
||||||
{ COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
|
{ COUNT_FUNC, COUNT_DISTINCT_FUNC, SUM_FUNC, SUM_DISTINCT_FUNC, AVG_FUNC,
|
||||||
AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC,
|
AVG_DISTINCT_FUNC, MIN_FUNC, MAX_FUNC, STD_FUNC,
|
||||||
VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC
|
VARIANCE_FUNC, SUM_BIT_FUNC, UDF_SUM_FUNC, GROUP_CONCAT_FUNC,
|
||||||
|
ROW_NUMBER_FUNC, RANK_FUNC, DENSE_RANK_FUNC, PERCENT_RANK_FUNC,
|
||||||
|
CUME_DIST_FUNC
|
||||||
};
|
};
|
||||||
|
|
||||||
Item **ref_by; /* pointer to a ref to the object used to register it */
|
Item **ref_by; /* pointer to a ref to the object used to register it */
|
||||||
|
@ -712,6 +714,7 @@ public:
|
||||||
class Item_sum_int :public Item_sum_num
|
class Item_sum_int :public Item_sum_num
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Item_sum_int(THD *thd): Item_sum_num(thd) {}
|
||||||
Item_sum_int(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {}
|
Item_sum_int(THD *thd, Item *item_par): Item_sum_num(thd, item_par) {}
|
||||||
Item_sum_int(THD *thd, List<Item> &list): Item_sum_num(thd, list) {}
|
Item_sum_int(THD *thd, List<Item> &list): Item_sum_num(thd, list) {}
|
||||||
Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {}
|
Item_sum_int(THD *thd, Item_sum_int *item) :Item_sum_num(thd, item) {}
|
||||||
|
@ -726,7 +729,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
class Item_sum_sum :public Item_sum_num,
|
class Item_sum_sum :public Item_sum_num,
|
||||||
public Type_handler_hybrid_field_type
|
public Type_handler_hybrid_field_type
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
double sum;
|
double sum;
|
||||||
|
|
13
sql/item_windowfunc.cc
Normal file
13
sql/item_windowfunc.cc
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include "item_windowfunc.h"
|
||||||
|
|
||||||
|
bool
|
||||||
|
Item_window_func::fix_fields(THD *thd, Item **ref)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(fixed == 0);
|
||||||
|
|
||||||
|
if (window_func->fix_fields(thd, ref))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
fixed= 1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
177
sql/item_windowfunc.h
Normal file
177
sql/item_windowfunc.h
Normal file
|
@ -0,0 +1,177 @@
|
||||||
|
#ifndef ITEM_WINDOWFUNC_INCLUDED
|
||||||
|
#define ITEM_WINDOWFUNC_INCLUDED
|
||||||
|
|
||||||
|
#include "my_global.h"
|
||||||
|
#include "item.h"
|
||||||
|
|
||||||
|
class Window_spec;
|
||||||
|
|
||||||
|
|
||||||
|
class Item_sum_row_number: public Item_sum_int
|
||||||
|
{
|
||||||
|
longlong count;
|
||||||
|
|
||||||
|
void clear() {}
|
||||||
|
bool add() { return false; }
|
||||||
|
void update_field() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_sum_row_number(THD *thd)
|
||||||
|
: Item_sum_int(thd), count(0) {}
|
||||||
|
|
||||||
|
enum Sumfunctype sum_func () const
|
||||||
|
{
|
||||||
|
return ROW_NUMBER_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*func_name() const
|
||||||
|
{
|
||||||
|
return "row_number";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Item_sum_rank: public Item_sum_int
|
||||||
|
{
|
||||||
|
longlong rank;
|
||||||
|
|
||||||
|
void clear() {}
|
||||||
|
bool add() { return false; }
|
||||||
|
void update_field() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_sum_rank(THD *thd)
|
||||||
|
: Item_sum_int(thd), rank(0) {}
|
||||||
|
|
||||||
|
enum Sumfunctype sum_func () const
|
||||||
|
{
|
||||||
|
return RANK_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*func_name() const
|
||||||
|
{
|
||||||
|
return "rank";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Item_sum_dense_rank: public Item_sum_int
|
||||||
|
{
|
||||||
|
longlong dense_rank;
|
||||||
|
|
||||||
|
void clear() {}
|
||||||
|
bool add() { return false; }
|
||||||
|
void update_field() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_sum_dense_rank(THD *thd)
|
||||||
|
: Item_sum_int(thd), dense_rank(0) {}
|
||||||
|
enum Sumfunctype sum_func () const
|
||||||
|
{
|
||||||
|
return DENSE_RANK_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*func_name() const
|
||||||
|
{
|
||||||
|
return "dense_rank";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Item_sum_percent_rank: public Item_sum_num
|
||||||
|
{
|
||||||
|
longlong rank;
|
||||||
|
longlong partition_rows;
|
||||||
|
|
||||||
|
void clear() {}
|
||||||
|
bool add() { return false; }
|
||||||
|
void update_field() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_sum_percent_rank(THD *thd)
|
||||||
|
: Item_sum_num(thd), rank(0), partition_rows(0) {}
|
||||||
|
|
||||||
|
double val_real() { return 0; }
|
||||||
|
|
||||||
|
enum Sumfunctype sum_func () const
|
||||||
|
{
|
||||||
|
return PERCENT_RANK_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*func_name() const
|
||||||
|
{
|
||||||
|
return "percent_rank";
|
||||||
|
}
|
||||||
|
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Item_sum_cume_dist: public Item_sum_num
|
||||||
|
{
|
||||||
|
longlong count;
|
||||||
|
longlong partition_rows;
|
||||||
|
|
||||||
|
void clear() {}
|
||||||
|
bool add() { return false; }
|
||||||
|
void update_field() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_sum_cume_dist(THD *thd)
|
||||||
|
: Item_sum_num(thd), count(0), partition_rows(0) {}
|
||||||
|
|
||||||
|
double val_real() { return 0; }
|
||||||
|
|
||||||
|
enum Sumfunctype sum_func () const
|
||||||
|
{
|
||||||
|
return CUME_DIST_FUNC;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*func_name() const
|
||||||
|
{
|
||||||
|
return "cume_dist";
|
||||||
|
}
|
||||||
|
|
||||||
|
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Item_window_func : public Item_result_field
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Item_sum *window_func;
|
||||||
|
LEX_STRING *window_name;
|
||||||
|
Window_spec *window_spec;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Item_window_func(THD *thd, Item_sum *win_func, LEX_STRING *win_name)
|
||||||
|
: Item_result_field(thd), window_func(win_func),
|
||||||
|
window_name(win_name), window_spec(NULL) {}
|
||||||
|
|
||||||
|
Item_window_func(THD *thd, Item_sum *win_func, Window_spec *win_spec)
|
||||||
|
: Item_result_field(thd), window_func(win_func),
|
||||||
|
window_name(NULL), window_spec(win_spec) {}
|
||||||
|
|
||||||
|
enum Item::Type type() const { return Item::WINDOW_FUNC_ITEM; }
|
||||||
|
|
||||||
|
enum_field_types field_type() const { return window_func->field_type(); }
|
||||||
|
|
||||||
|
double val_real() { return window_func->val_real(); }
|
||||||
|
|
||||||
|
longlong val_int() { return window_func->val_int(); }
|
||||||
|
|
||||||
|
String* val_str(String* str) { return window_func->val_str(str); }
|
||||||
|
|
||||||
|
my_decimal* val_decimal(my_decimal* dec)
|
||||||
|
{ return window_func->val_decimal(dec); }
|
||||||
|
|
||||||
|
void fix_length_and_dec() { }
|
||||||
|
|
||||||
|
const char* func_name() const { return "WF"; }
|
||||||
|
|
||||||
|
bool fix_fields(THD *thd, Item **ref);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* ITEM_WINDOWFUNC_INCLUDED */
|
13
sql/lex.h
13
sql/lex.h
|
@ -221,6 +221,7 @@ static SYMBOL symbols[] = {
|
||||||
{ "EVERY", SYM(EVERY_SYM)},
|
{ "EVERY", SYM(EVERY_SYM)},
|
||||||
{ "EXAMINED", SYM(EXAMINED_SYM)},
|
{ "EXAMINED", SYM(EXAMINED_SYM)},
|
||||||
{ "EXCHANGE", SYM(EXCHANGE_SYM)},
|
{ "EXCHANGE", SYM(EXCHANGE_SYM)},
|
||||||
|
{ "EXCLUDE", SYM(EXCLUDE_SYM)},
|
||||||
{ "EXECUTE", SYM(EXECUTE_SYM)},
|
{ "EXECUTE", SYM(EXECUTE_SYM)},
|
||||||
{ "EXISTS", SYM(EXISTS)},
|
{ "EXISTS", SYM(EXISTS)},
|
||||||
{ "EXIT", SYM(EXIT_SYM)},
|
{ "EXIT", SYM(EXIT_SYM)},
|
||||||
|
@ -241,6 +242,7 @@ static SYMBOL symbols[] = {
|
||||||
{ "FLOAT4", SYM(FLOAT_SYM)},
|
{ "FLOAT4", SYM(FLOAT_SYM)},
|
||||||
{ "FLOAT8", SYM(DOUBLE_SYM)},
|
{ "FLOAT8", SYM(DOUBLE_SYM)},
|
||||||
{ "FLUSH", SYM(FLUSH_SYM)},
|
{ "FLUSH", SYM(FLUSH_SYM)},
|
||||||
|
{ "FOLLOWING", SYM(FOLLOWING_SYM)},
|
||||||
{ "FOR", SYM(FOR_SYM)},
|
{ "FOR", SYM(FOR_SYM)},
|
||||||
{ "FORCE", SYM(FORCE_SYM)},
|
{ "FORCE", SYM(FORCE_SYM)},
|
||||||
{ "FOREIGN", SYM(FOREIGN)},
|
{ "FOREIGN", SYM(FOREIGN)},
|
||||||
|
@ -425,9 +427,11 @@ static SYMBOL symbols[] = {
|
||||||
{ "OPTIONALLY", SYM(OPTIONALLY)},
|
{ "OPTIONALLY", SYM(OPTIONALLY)},
|
||||||
{ "OR", SYM(OR_SYM)},
|
{ "OR", SYM(OR_SYM)},
|
||||||
{ "ORDER", SYM(ORDER_SYM)},
|
{ "ORDER", SYM(ORDER_SYM)},
|
||||||
|
{ "OTHERS", SYM(OTHERS_SYM)},
|
||||||
{ "OUT", SYM(OUT_SYM)},
|
{ "OUT", SYM(OUT_SYM)},
|
||||||
{ "OUTER", SYM(OUTER)},
|
{ "OUTER", SYM(OUTER)},
|
||||||
{ "OUTFILE", SYM(OUTFILE)},
|
{ "OUTFILE", SYM(OUTFILE)},
|
||||||
|
{ "OVER", SYM(OVER_SYM)},
|
||||||
{ "OWNER", SYM(OWNER_SYM)},
|
{ "OWNER", SYM(OWNER_SYM)},
|
||||||
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
|
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
|
||||||
{ "PAGE", SYM(PAGE_SYM)},
|
{ "PAGE", SYM(PAGE_SYM)},
|
||||||
|
@ -446,6 +450,7 @@ static SYMBOL symbols[] = {
|
||||||
{ "POINT", SYM(POINT_SYM)},
|
{ "POINT", SYM(POINT_SYM)},
|
||||||
{ "POLYGON", SYM(POLYGON)},
|
{ "POLYGON", SYM(POLYGON)},
|
||||||
{ "PORT", SYM(PORT_SYM)},
|
{ "PORT", SYM(PORT_SYM)},
|
||||||
|
{ "PRECEDING", SYM(PRECEDING_SYM)},
|
||||||
{ "PRECISION", SYM(PRECISION)},
|
{ "PRECISION", SYM(PRECISION)},
|
||||||
{ "PREPARE", SYM(PREPARE_SYM)},
|
{ "PREPARE", SYM(PREPARE_SYM)},
|
||||||
{ "PRESERVE", SYM(PRESERVE_SYM)},
|
{ "PRESERVE", SYM(PRESERVE_SYM)},
|
||||||
|
@ -601,6 +606,7 @@ static SYMBOL symbols[] = {
|
||||||
{ "TEXT", SYM(TEXT_SYM)},
|
{ "TEXT", SYM(TEXT_SYM)},
|
||||||
{ "THAN", SYM(THAN_SYM)},
|
{ "THAN", SYM(THAN_SYM)},
|
||||||
{ "THEN", SYM(THEN_SYM)},
|
{ "THEN", SYM(THEN_SYM)},
|
||||||
|
{ "TIES", SYM(TIES_SYM)},
|
||||||
{ "TIME", SYM(TIME_SYM)},
|
{ "TIME", SYM(TIME_SYM)},
|
||||||
{ "TIMESTAMP", SYM(TIMESTAMP)},
|
{ "TIMESTAMP", SYM(TIMESTAMP)},
|
||||||
{ "TIMESTAMPADD", SYM(TIMESTAMP_ADD)},
|
{ "TIMESTAMPADD", SYM(TIMESTAMP_ADD)},
|
||||||
|
@ -618,6 +624,7 @@ static SYMBOL symbols[] = {
|
||||||
{ "TRUNCATE", SYM(TRUNCATE_SYM)},
|
{ "TRUNCATE", SYM(TRUNCATE_SYM)},
|
||||||
{ "TYPE", SYM(TYPE_SYM)},
|
{ "TYPE", SYM(TYPE_SYM)},
|
||||||
{ "TYPES", SYM(TYPES_SYM)},
|
{ "TYPES", SYM(TYPES_SYM)},
|
||||||
|
{ "UNBOUNDED", SYM(UNBOUNDED_SYM)},
|
||||||
{ "UNCOMMITTED", SYM(UNCOMMITTED_SYM)},
|
{ "UNCOMMITTED", SYM(UNCOMMITTED_SYM)},
|
||||||
{ "UNDEFINED", SYM(UNDEFINED_SYM)},
|
{ "UNDEFINED", SYM(UNDEFINED_SYM)},
|
||||||
{ "UNDO_BUFFER_SIZE", SYM(UNDO_BUFFER_SIZE_SYM)},
|
{ "UNDO_BUFFER_SIZE", SYM(UNDO_BUFFER_SIZE_SYM)},
|
||||||
|
@ -659,6 +666,7 @@ static SYMBOL symbols[] = {
|
||||||
{ "WHEN", SYM(WHEN_SYM)},
|
{ "WHEN", SYM(WHEN_SYM)},
|
||||||
{ "WHERE", SYM(WHERE)},
|
{ "WHERE", SYM(WHERE)},
|
||||||
{ "WHILE", SYM(WHILE_SYM)},
|
{ "WHILE", SYM(WHILE_SYM)},
|
||||||
|
{ "WINDOW", SYM(WINDOW_SYM)},
|
||||||
{ "WITH", SYM(WITH)},
|
{ "WITH", SYM(WITH)},
|
||||||
{ "WORK", SYM(WORK_SYM)},
|
{ "WORK", SYM(WORK_SYM)},
|
||||||
{ "WRAPPER", SYM(WRAPPER_SYM)},
|
{ "WRAPPER", SYM(WRAPPER_SYM)},
|
||||||
|
@ -681,10 +689,12 @@ static SYMBOL sql_functions[] = {
|
||||||
{ "BIT_XOR", SYM(BIT_XOR)},
|
{ "BIT_XOR", SYM(BIT_XOR)},
|
||||||
{ "CAST", SYM(CAST_SYM)},
|
{ "CAST", SYM(CAST_SYM)},
|
||||||
{ "COUNT", SYM(COUNT_SYM)},
|
{ "COUNT", SYM(COUNT_SYM)},
|
||||||
|
{ "CUME_DIST", SYM(CUME_DIST_SYM)},
|
||||||
{ "CURDATE", SYM(CURDATE)},
|
{ "CURDATE", SYM(CURDATE)},
|
||||||
{ "CURTIME", SYM(CURTIME)},
|
{ "CURTIME", SYM(CURTIME)},
|
||||||
{ "DATE_ADD", SYM(DATE_ADD_INTERVAL)},
|
{ "DATE_ADD", SYM(DATE_ADD_INTERVAL)},
|
||||||
{ "DATE_SUB", SYM(DATE_SUB_INTERVAL)},
|
{ "DATE_SUB", SYM(DATE_SUB_INTERVAL)},
|
||||||
|
{ "DENSE_RANK", SYM(DENSE_RANK_SYM)},
|
||||||
{ "EXTRACT", SYM(EXTRACT_SYM)},
|
{ "EXTRACT", SYM(EXTRACT_SYM)},
|
||||||
{ "GROUP_CONCAT", SYM(GROUP_CONCAT_SYM)},
|
{ "GROUP_CONCAT", SYM(GROUP_CONCAT_SYM)},
|
||||||
{ "MAX", SYM(MAX_SYM)},
|
{ "MAX", SYM(MAX_SYM)},
|
||||||
|
@ -692,6 +702,9 @@ static SYMBOL sql_functions[] = {
|
||||||
{ "MIN", SYM(MIN_SYM)},
|
{ "MIN", SYM(MIN_SYM)},
|
||||||
{ "NOW", SYM(NOW_SYM)},
|
{ "NOW", SYM(NOW_SYM)},
|
||||||
{ "POSITION", SYM(POSITION_SYM)},
|
{ "POSITION", SYM(POSITION_SYM)},
|
||||||
|
{ "PERCENT_RANK", SYM(PERCENT_RANK_SYM)},
|
||||||
|
{ "RANK", SYM(RANK_SYM)},
|
||||||
|
{ "ROW_NUMBER", SYM(ROW_NUMBER_SYM)},
|
||||||
{ "SESSION_USER", SYM(USER)},
|
{ "SESSION_USER", SYM(USER)},
|
||||||
{ "STD", SYM(STD_SYM)},
|
{ "STD", SYM(STD_SYM)},
|
||||||
{ "STDDEV", SYM(STD_SYM)},
|
{ "STDDEV", SYM(STD_SYM)},
|
||||||
|
|
|
@ -7136,3 +7136,14 @@ ER_KILL_QUERY_DENIED_ERROR
|
||||||
eng "You are not owner of query %lu"
|
eng "You are not owner of query %lu"
|
||||||
ger "Sie sind nicht Eigentümer von Abfrage %lu"
|
ger "Sie sind nicht Eigentümer von Abfrage %lu"
|
||||||
rus "Вы не являетесь владельцем запроса %lu"
|
rus "Вы не являетесь владельцем запроса %lu"
|
||||||
|
ER_WRONG_WINDOW_SPEC_NAME
|
||||||
|
eng "Window specification with name '%s' is not defined"
|
||||||
|
ER_DUP_WINDOW_NAME
|
||||||
|
eng "Multiple window specifications with the same name '%s'"
|
||||||
|
ER_PARTITION_LIST_IN_REFERENCING_WINDOW_SPEC
|
||||||
|
eng "Window specification referencing another one '%s' cannot contain partition list"
|
||||||
|
ER_ORDER_LIST_IN_REFERENCING_WINDOW_SPEC
|
||||||
|
eng "Referenced window specification '%s' already contains order list"
|
||||||
|
ER_WINDOW_FRAME_IN_REFERENCED_WINDOW_SPEC
|
||||||
|
eng "Referenced window specification '%s' cannot contain window frame"
|
||||||
|
|
||||||
|
|
|
@ -546,6 +546,14 @@ void lex_start(THD *thd)
|
||||||
lex->stmt_var_list.empty();
|
lex->stmt_var_list.empty();
|
||||||
lex->proc_list.elements=0;
|
lex->proc_list.elements=0;
|
||||||
|
|
||||||
|
lex->save_group_list.empty();
|
||||||
|
lex->save_order_list.empty();
|
||||||
|
lex->win_ref= NULL;
|
||||||
|
lex->win_frame= NULL;
|
||||||
|
lex->frame_top_bound= NULL;
|
||||||
|
lex->frame_bottom_bound= NULL;
|
||||||
|
lex->win_spec= NULL;
|
||||||
|
|
||||||
lex->is_lex_started= TRUE;
|
lex->is_lex_started= TRUE;
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
@ -1926,6 +1934,7 @@ void st_select_lex::init_query()
|
||||||
select_list_tables= 0;
|
select_list_tables= 0;
|
||||||
m_non_agg_field_used= false;
|
m_non_agg_field_used= false;
|
||||||
m_agg_func_used= false;
|
m_agg_func_used= false;
|
||||||
|
window_specs.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void st_select_lex::init_select()
|
void st_select_lex::init_select()
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "mem_root_array.h"
|
#include "mem_root_array.h"
|
||||||
#include "sql_cmd.h"
|
#include "sql_cmd.h"
|
||||||
#include "sql_alter.h" // Alter_info
|
#include "sql_alter.h" // Alter_info
|
||||||
|
#include "sql_window.h"
|
||||||
|
|
||||||
/* YACC and LEX Definitions */
|
/* YACC and LEX Definitions */
|
||||||
|
|
||||||
|
@ -1070,6 +1071,17 @@ public:
|
||||||
void set_non_agg_field_used(bool val) { m_non_agg_field_used= val; }
|
void set_non_agg_field_used(bool val) { m_non_agg_field_used= val; }
|
||||||
void set_agg_func_used(bool val) { m_agg_func_used= val; }
|
void set_agg_func_used(bool val) { m_agg_func_used= val; }
|
||||||
|
|
||||||
|
List<Window_spec> window_specs;
|
||||||
|
void prepare_add_window_spec(THD *thd);
|
||||||
|
bool add_window_def(THD *thd, LEX_STRING *win_name, LEX_STRING *win_ref,
|
||||||
|
SQL_I_List<ORDER> win_partition_list,
|
||||||
|
SQL_I_List<ORDER> win_order_list,
|
||||||
|
Window_frame *win_frame);
|
||||||
|
bool add_window_spec(THD *thd, LEX_STRING *win_ref,
|
||||||
|
SQL_I_List<ORDER> win_partition_list,
|
||||||
|
SQL_I_List<ORDER> win_order_list,
|
||||||
|
Window_frame *win_frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_non_agg_field_used;
|
bool m_non_agg_field_used;
|
||||||
bool m_agg_func_used;
|
bool m_agg_func_used;
|
||||||
|
@ -2706,6 +2718,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SQL_I_List<ORDER> save_group_list;
|
||||||
|
SQL_I_List<ORDER> save_order_list;
|
||||||
|
LEX_STRING *win_ref;
|
||||||
|
Window_frame *win_frame;
|
||||||
|
Window_frame_bound *frame_top_bound;
|
||||||
|
Window_frame_bound *frame_bottom_bound;
|
||||||
|
Window_spec *win_spec;
|
||||||
|
|
||||||
inline void free_set_stmt_mem_root()
|
inline void free_set_stmt_mem_root()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!is_arena_for_set_stmt());
|
DBUG_ASSERT(!is_arena_for_set_stmt());
|
||||||
|
|
|
@ -7816,6 +7816,53 @@ TABLE_LIST *st_select_lex::convert_right_join()
|
||||||
DBUG_RETURN(tab1);
|
DBUG_RETURN(tab1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void st_select_lex::prepare_add_window_spec(THD *thd)
|
||||||
|
{
|
||||||
|
LEX *lex= thd->lex;
|
||||||
|
lex->save_group_list= group_list;
|
||||||
|
lex->save_order_list= order_list;
|
||||||
|
lex->win_ref= NULL;
|
||||||
|
lex->win_frame= NULL;
|
||||||
|
lex->frame_top_bound= NULL;
|
||||||
|
lex->frame_bottom_bound= NULL;
|
||||||
|
group_list.empty();
|
||||||
|
order_list.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool st_select_lex::add_window_def(THD *thd,
|
||||||
|
LEX_STRING *win_name,
|
||||||
|
LEX_STRING *win_ref,
|
||||||
|
SQL_I_List<ORDER> win_partition_list,
|
||||||
|
SQL_I_List<ORDER> win_order_list,
|
||||||
|
Window_frame *win_frame)
|
||||||
|
{
|
||||||
|
Window_def *win_def= new (thd->mem_root) Window_def(win_name,
|
||||||
|
win_ref,
|
||||||
|
win_partition_list,
|
||||||
|
win_order_list,
|
||||||
|
win_frame);
|
||||||
|
group_list= thd->lex->save_group_list;
|
||||||
|
order_list= thd->lex->save_order_list;
|
||||||
|
return (win_def == NULL || window_specs.push_back(win_def));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool st_select_lex::add_window_spec(THD *thd,
|
||||||
|
LEX_STRING *win_ref,
|
||||||
|
SQL_I_List<ORDER> win_partition_list,
|
||||||
|
SQL_I_List<ORDER> win_order_list,
|
||||||
|
Window_frame *win_frame)
|
||||||
|
{
|
||||||
|
Window_spec *win_spec= new (thd->mem_root) Window_spec(win_ref,
|
||||||
|
win_partition_list,
|
||||||
|
win_order_list,
|
||||||
|
win_frame);
|
||||||
|
group_list= thd->lex->save_group_list;
|
||||||
|
order_list= thd->lex->save_order_list;
|
||||||
|
thd->lex->win_spec= win_spec;
|
||||||
|
return (win_spec == NULL || window_specs.push_back(win_spec));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set lock for all tables in current select level.
|
Set lock for all tables in current select level.
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "log_slow.h"
|
#include "log_slow.h"
|
||||||
#include "sql_derived.h"
|
#include "sql_derived.h"
|
||||||
#include "sql_statistics.h"
|
#include "sql_statistics.h"
|
||||||
|
#include "sql_window.h"
|
||||||
|
|
||||||
#include "debug_sync.h" // DEBUG_SYNC
|
#include "debug_sync.h" // DEBUG_SYNC
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
|
@ -621,6 +622,7 @@ setup_without_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||||
COND **conds,
|
COND **conds,
|
||||||
ORDER *order,
|
ORDER *order,
|
||||||
ORDER *group,
|
ORDER *group,
|
||||||
|
List<Window_spec> &win_specs,
|
||||||
bool *hidden_group_fields,
|
bool *hidden_group_fields,
|
||||||
uint *reserved)
|
uint *reserved)
|
||||||
{
|
{
|
||||||
|
@ -654,6 +656,8 @@ setup_without_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||||
res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
|
res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
|
||||||
group, hidden_group_fields);
|
group, hidden_group_fields);
|
||||||
thd->lex->allow_sum_func= save_allow_sum_func;
|
thd->lex->allow_sum_func= save_allow_sum_func;
|
||||||
|
res= res || setup_windows(thd, ref_pointer_array, tables, fields, all_fields,
|
||||||
|
win_specs);
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -794,6 +798,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
||||||
if (setup_without_group(thd, ref_ptrs, tables_list,
|
if (setup_without_group(thd, ref_ptrs, tables_list,
|
||||||
select_lex->leaf_tables, fields_list,
|
select_lex->leaf_tables, fields_list,
|
||||||
all_fields, &conds, order, group_list,
|
all_fields, &conds, order, group_list,
|
||||||
|
select_lex->window_specs,
|
||||||
&hidden_group_fields,
|
&hidden_group_fields,
|
||||||
&select_lex->select_n_reserved))
|
&select_lex->select_n_reserved))
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
|
|
79
sql/sql_window.cc
Normal file
79
sql/sql_window.cc
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
#include "sql_select.h"
|
||||||
|
#include "sql_window.h"
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Window_spec::check_window_names(List_iterator_fast<Window_spec> &it)
|
||||||
|
{
|
||||||
|
char *name= this->name();
|
||||||
|
char *ref_name= window_reference();
|
||||||
|
bool win_ref_is_resolved= false;
|
||||||
|
it.rewind();
|
||||||
|
Window_spec *win_spec;
|
||||||
|
while((win_spec= it++) && win_spec != this)
|
||||||
|
{
|
||||||
|
char *win_spec_name= win_spec->name();
|
||||||
|
if (win_spec_name)
|
||||||
|
{
|
||||||
|
if (name && my_strcasecmp(system_charset_info, name, win_spec_name) == 0)
|
||||||
|
{
|
||||||
|
my_error(ER_DUP_WINDOW_NAME, MYF(0), name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ref_name &&
|
||||||
|
my_strcasecmp(system_charset_info, ref_name, win_spec_name) == 0)
|
||||||
|
{
|
||||||
|
if (win_spec->partition_list.elements)
|
||||||
|
{
|
||||||
|
my_error(ER_PARTITION_LIST_IN_REFERENCING_WINDOW_SPEC, MYF(0),
|
||||||
|
ref_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (win_spec->order_list.elements && order_list.elements)
|
||||||
|
{
|
||||||
|
my_error(ER_ORDER_LIST_IN_REFERENCING_WINDOW_SPEC, MYF(0), ref_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (win_spec->window_frame)
|
||||||
|
{
|
||||||
|
my_error(ER_WINDOW_FRAME_IN_REFERENCED_WINDOW_SPEC, MYF(0), ref_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
referenced_win_spec=win_spec;
|
||||||
|
win_ref_is_resolved= true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ref_name && !win_ref_is_resolved)
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_WINDOW_SPEC_NAME, MYF(0), ref_name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
||||||
|
List<Item> &fields, List<Item> &all_fields,
|
||||||
|
List<Window_spec> win_specs)
|
||||||
|
{
|
||||||
|
Window_spec *win_spec;
|
||||||
|
DBUG_ENTER("setup_windows");
|
||||||
|
List_iterator<Window_spec> it(win_specs);
|
||||||
|
List_iterator_fast<Window_spec> itp(win_specs);
|
||||||
|
|
||||||
|
while ((win_spec= it++))
|
||||||
|
{
|
||||||
|
bool hidden_group_fields;
|
||||||
|
if (win_spec->check_window_names(itp) ||
|
||||||
|
setup_group(thd, ref_pointer_array, tables, fields, all_fields,
|
||||||
|
win_spec->partition_list.first, &hidden_group_fields) ||
|
||||||
|
setup_order(thd, ref_pointer_array, tables, fields, all_fields,
|
||||||
|
win_spec->order_list.first))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
124
sql/sql_window.h
Normal file
124
sql/sql_window.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
|
||||||
|
#ifndef SQL_WINDOW_INCLUDED
|
||||||
|
#define SQL_WINDOW_INCLUDED
|
||||||
|
|
||||||
|
#include "my_global.h"
|
||||||
|
#include "item.h"
|
||||||
|
|
||||||
|
class Window_frame_bound : public Sql_alloc
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Bound_precedence_type
|
||||||
|
{
|
||||||
|
PRECEDING,
|
||||||
|
CURRENT, // Used for CURRENT ROW window frame bounds
|
||||||
|
FOLLOWING
|
||||||
|
};
|
||||||
|
|
||||||
|
Bound_precedence_type precedence_type;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
For UNBOUNDED PRECEDING / UNBOUNDED FOLLOWING window frame bounds
|
||||||
|
precedence type is seto to PRECEDING / FOLLOWING and
|
||||||
|
offset is set to NULL.
|
||||||
|
The offset is not meaningful with precedence type CURRENT
|
||||||
|
*/
|
||||||
|
Item *offset;
|
||||||
|
|
||||||
|
Window_frame_bound(Bound_precedence_type prec_type,
|
||||||
|
Item *offset_val)
|
||||||
|
: precedence_type(prec_type), offset(offset_val) {}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Window_frame : public Sql_alloc
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum Frame_units
|
||||||
|
{
|
||||||
|
UNITS_ROWS,
|
||||||
|
UNITS_RANGE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Frame_exclusion
|
||||||
|
{
|
||||||
|
EXCL_NONE,
|
||||||
|
EXCL_CURRENT_ROW,
|
||||||
|
EXCL_GROUP,
|
||||||
|
EXCL_TIES
|
||||||
|
};
|
||||||
|
|
||||||
|
Frame_units units;
|
||||||
|
|
||||||
|
Window_frame_bound *top_bound;
|
||||||
|
|
||||||
|
Window_frame_bound *bottom_bound;
|
||||||
|
|
||||||
|
Frame_exclusion exclusion;
|
||||||
|
|
||||||
|
Window_frame(Frame_units win_frame_units,
|
||||||
|
Window_frame_bound *win_frame_top_bound,
|
||||||
|
Window_frame_bound *win_frame_bottom_bound,
|
||||||
|
Frame_exclusion win_frame_exclusion)
|
||||||
|
: units(win_frame_units), top_bound(win_frame_top_bound),
|
||||||
|
bottom_bound(win_frame_bottom_bound), exclusion(win_frame_exclusion) {}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Window_spec : public Sql_alloc
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
LEX_STRING *window_ref;
|
||||||
|
|
||||||
|
SQL_I_List<ORDER> partition_list;
|
||||||
|
|
||||||
|
SQL_I_List<ORDER> order_list;
|
||||||
|
|
||||||
|
Window_frame *window_frame;
|
||||||
|
|
||||||
|
Window_spec *referenced_win_spec;
|
||||||
|
|
||||||
|
Window_spec(LEX_STRING *win_ref,
|
||||||
|
SQL_I_List<ORDER> part_list,
|
||||||
|
SQL_I_List<ORDER> ord_list,
|
||||||
|
Window_frame *win_frame)
|
||||||
|
: window_ref(win_ref), partition_list(part_list), order_list(ord_list),
|
||||||
|
window_frame(win_frame), referenced_win_spec(NULL) {}
|
||||||
|
|
||||||
|
virtual char *name() { return NULL; }
|
||||||
|
|
||||||
|
bool check_window_names(List_iterator_fast<Window_spec> &it);
|
||||||
|
|
||||||
|
char *window_reference() { return window_ref ? window_ref->str : NULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class Window_def : public Window_spec
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
LEX_STRING *window_name;
|
||||||
|
|
||||||
|
Window_def(LEX_STRING *win_name,
|
||||||
|
LEX_STRING *win_ref,
|
||||||
|
SQL_I_List<ORDER> part_list,
|
||||||
|
SQL_I_List<ORDER> ord_list,
|
||||||
|
Window_frame *win_frame)
|
||||||
|
: Window_spec(win_ref, part_list, ord_list, win_frame),
|
||||||
|
window_name(win_name) {}
|
||||||
|
|
||||||
|
char *name() { return window_name->str; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
int setup_windows(THD *thd, Ref_ptr_array ref_pointer_array, TABLE_LIST *tables,
|
||||||
|
List<Item> &fields, List<Item> &all_fields,
|
||||||
|
List<Window_spec> win_specs);
|
||||||
|
|
||||||
|
#endif /* SQL_WINDOW_INCLUDED */
|
262
sql/sql_yacc.yy
262
sql/sql_yacc.yy
|
@ -54,6 +54,8 @@
|
||||||
#include "sql_handler.h" // Sql_cmd_handler_*
|
#include "sql_handler.h" // Sql_cmd_handler_*
|
||||||
#include "sql_signal.h"
|
#include "sql_signal.h"
|
||||||
#include "sql_get_diagnostics.h" // Sql_cmd_get_diagnostics
|
#include "sql_get_diagnostics.h" // Sql_cmd_get_diagnostics
|
||||||
|
#include "sql_window.h"
|
||||||
|
#include "item_windowfunc.h"
|
||||||
#include "event_parse_data.h"
|
#include "event_parse_data.h"
|
||||||
#include "create_options.h"
|
#include "create_options.h"
|
||||||
#include <myisam.h>
|
#include <myisam.h>
|
||||||
|
@ -962,6 +964,8 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
|
||||||
handlerton *db_type;
|
handlerton *db_type;
|
||||||
st_select_lex *select_lex;
|
st_select_lex *select_lex;
|
||||||
struct p_elem_val *p_elem_value;
|
struct p_elem_val *p_elem_value;
|
||||||
|
class Window_frame *window_frame;
|
||||||
|
class Window_frame_bound *window_frame_bound;
|
||||||
udf_func *udf;
|
udf_func *udf;
|
||||||
|
|
||||||
/* enums */
|
/* enums */
|
||||||
|
@ -987,6 +991,9 @@ bool LEX::set_bincmp(CHARSET_INFO *cs, bool bin)
|
||||||
enum sp_variable::enum_mode spvar_mode;
|
enum sp_variable::enum_mode spvar_mode;
|
||||||
enum thr_lock_type lock_type;
|
enum thr_lock_type lock_type;
|
||||||
enum enum_mysql_timestamp_type date_time_type;
|
enum enum_mysql_timestamp_type date_time_type;
|
||||||
|
enum Window_frame_bound::Bound_precedence_type bound_precedence_type;
|
||||||
|
enum Window_frame::Frame_units frame_units;
|
||||||
|
enum Window_frame::Frame_exclusion frame_exclusion;
|
||||||
DDL_options_st object_ddl_options;
|
DDL_options_st object_ddl_options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -998,10 +1005,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%parse-param { THD *thd }
|
%parse-param { THD *thd }
|
||||||
%lex-param { THD *thd }
|
%lex-param { THD *thd }
|
||||||
/*
|
/*
|
||||||
Currently there are 121 shift/reduce conflicts.
|
Currently there are 124 shift/reduce conflicts.
|
||||||
We should not introduce new conflicts any more.
|
We should not introduce new conflicts any more.
|
||||||
*/
|
*/
|
||||||
%expect 121
|
%expect 124
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Comments for TOKENS.
|
Comments for TOKENS.
|
||||||
|
@ -1124,6 +1131,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token CREATE /* SQL-2003-R */
|
%token CREATE /* SQL-2003-R */
|
||||||
%token CROSS /* SQL-2003-R */
|
%token CROSS /* SQL-2003-R */
|
||||||
%token CUBE_SYM /* SQL-2003-R */
|
%token CUBE_SYM /* SQL-2003-R */
|
||||||
|
%token CUME_DIST_SYM
|
||||||
%token CURDATE /* MYSQL-FUNC */
|
%token CURDATE /* MYSQL-FUNC */
|
||||||
%token CURRENT_SYM /* SQL-2003-R */
|
%token CURRENT_SYM /* SQL-2003-R */
|
||||||
%token CURRENT_USER /* SQL-2003-R */
|
%token CURRENT_USER /* SQL-2003-R */
|
||||||
|
@ -1154,6 +1162,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token DELAYED_SYM
|
%token DELAYED_SYM
|
||||||
%token DELAY_KEY_WRITE_SYM
|
%token DELAY_KEY_WRITE_SYM
|
||||||
%token DELETE_SYM /* SQL-2003-R */
|
%token DELETE_SYM /* SQL-2003-R */
|
||||||
|
%token DENSE_RANK_SYM
|
||||||
%token DESC /* SQL-2003-N */
|
%token DESC /* SQL-2003-N */
|
||||||
%token DESCRIBE /* SQL-2003-R */
|
%token DESCRIBE /* SQL-2003-R */
|
||||||
%token DES_KEY_FILE
|
%token DES_KEY_FILE
|
||||||
|
@ -1195,6 +1204,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token EVERY_SYM /* SQL-2003-N */
|
%token EVERY_SYM /* SQL-2003-N */
|
||||||
%token EXCHANGE_SYM
|
%token EXCHANGE_SYM
|
||||||
%token EXAMINED_SYM
|
%token EXAMINED_SYM
|
||||||
|
%token EXCLUDE_SYM
|
||||||
%token EXECUTE_SYM /* SQL-2003-R */
|
%token EXECUTE_SYM /* SQL-2003-R */
|
||||||
%token EXISTS /* SQL-2003-R */
|
%token EXISTS /* SQL-2003-R */
|
||||||
%token EXIT_SYM
|
%token EXIT_SYM
|
||||||
|
@ -1213,6 +1223,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token FLOAT_NUM
|
%token FLOAT_NUM
|
||||||
%token FLOAT_SYM /* SQL-2003-R */
|
%token FLOAT_SYM /* SQL-2003-R */
|
||||||
%token FLUSH_SYM
|
%token FLUSH_SYM
|
||||||
|
%token FOLLOWING_SYM
|
||||||
%token FORCE_SYM
|
%token FORCE_SYM
|
||||||
%token FOREIGN /* SQL-2003-R */
|
%token FOREIGN /* SQL-2003-R */
|
||||||
%token FOR_SYM /* SQL-2003-R */
|
%token FOR_SYM /* SQL-2003-R */
|
||||||
|
@ -1409,9 +1420,11 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token ORDER_SYM /* SQL-2003-R */
|
%token ORDER_SYM /* SQL-2003-R */
|
||||||
%token OR_OR_SYM /* OPERATOR */
|
%token OR_OR_SYM /* OPERATOR */
|
||||||
%token OR_SYM /* SQL-2003-R */
|
%token OR_SYM /* SQL-2003-R */
|
||||||
|
%token OTHERS_SYM
|
||||||
%token OUTER
|
%token OUTER
|
||||||
%token OUTFILE
|
%token OUTFILE
|
||||||
%token OUT_SYM /* SQL-2003-R */
|
%token OUT_SYM /* SQL-2003-R */
|
||||||
|
%token OVER_SYM
|
||||||
%token OWNER_SYM
|
%token OWNER_SYM
|
||||||
%token PACK_KEYS_SYM
|
%token PACK_KEYS_SYM
|
||||||
%token PAGE_SYM
|
%token PAGE_SYM
|
||||||
|
@ -1424,6 +1437,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token PARTITIONS_SYM
|
%token PARTITIONS_SYM
|
||||||
%token PARTITIONING_SYM
|
%token PARTITIONING_SYM
|
||||||
%token PASSWORD_SYM
|
%token PASSWORD_SYM
|
||||||
|
%token PERCENT_RANK_SYM
|
||||||
%token PERSISTENT_SYM
|
%token PERSISTENT_SYM
|
||||||
%token PHASE_SYM
|
%token PHASE_SYM
|
||||||
%token PLUGINS_SYM
|
%token PLUGINS_SYM
|
||||||
|
@ -1432,6 +1446,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token POLYGON
|
%token POLYGON
|
||||||
%token PORT_SYM
|
%token PORT_SYM
|
||||||
%token POSITION_SYM /* SQL-2003-N */
|
%token POSITION_SYM /* SQL-2003-N */
|
||||||
|
%token PRECEDING_SYM
|
||||||
%token PRECISION /* SQL-2003-R */
|
%token PRECISION /* SQL-2003-R */
|
||||||
%token PREPARE_SYM /* SQL-2003-R */
|
%token PREPARE_SYM /* SQL-2003-R */
|
||||||
%token PRESERVE_SYM
|
%token PRESERVE_SYM
|
||||||
|
@ -1449,6 +1464,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token QUERY_SYM
|
%token QUERY_SYM
|
||||||
%token QUICK
|
%token QUICK
|
||||||
%token RANGE_SYM /* SQL-2003-R */
|
%token RANGE_SYM /* SQL-2003-R */
|
||||||
|
%token RANK_SYM
|
||||||
%token READS_SYM /* SQL-2003-R */
|
%token READS_SYM /* SQL-2003-R */
|
||||||
%token READ_ONLY_SYM
|
%token READ_ONLY_SYM
|
||||||
%token READ_SYM /* SQL-2003-N */
|
%token READ_SYM /* SQL-2003-N */
|
||||||
|
@ -1498,6 +1514,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token ROW_FORMAT_SYM
|
%token ROW_FORMAT_SYM
|
||||||
%token ROW_SYM /* SQL-2003-R */
|
%token ROW_SYM /* SQL-2003-R */
|
||||||
%token ROW_COUNT_SYM /* SQL-2003-N */
|
%token ROW_COUNT_SYM /* SQL-2003-N */
|
||||||
|
%token ROW_NUMBER_SYM
|
||||||
%token RTREE_SYM
|
%token RTREE_SYM
|
||||||
%token SAVEPOINT_SYM /* SQL-2003-R */
|
%token SAVEPOINT_SYM /* SQL-2003-R */
|
||||||
%token SCHEDULE_SYM
|
%token SCHEDULE_SYM
|
||||||
|
@ -1588,6 +1605,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token TEXT_SYM
|
%token TEXT_SYM
|
||||||
%token THAN_SYM
|
%token THAN_SYM
|
||||||
%token THEN_SYM /* SQL-2003-R */
|
%token THEN_SYM /* SQL-2003-R */
|
||||||
|
%token TIES_SYM
|
||||||
%token TIMESTAMP /* SQL-2003-R */
|
%token TIMESTAMP /* SQL-2003-R */
|
||||||
%token TIMESTAMP_ADD
|
%token TIMESTAMP_ADD
|
||||||
%token TIMESTAMP_DIFF
|
%token TIMESTAMP_DIFF
|
||||||
|
@ -1608,6 +1626,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token TYPE_SYM /* SQL-2003-N */
|
%token TYPE_SYM /* SQL-2003-N */
|
||||||
%token UDF_RETURNS_SYM
|
%token UDF_RETURNS_SYM
|
||||||
%token ULONGLONG_NUM
|
%token ULONGLONG_NUM
|
||||||
|
%token UNBOUNDED_SYM
|
||||||
%token UNCOMMITTED_SYM /* SQL-2003-N */
|
%token UNCOMMITTED_SYM /* SQL-2003-N */
|
||||||
%token UNDEFINED_SYM
|
%token UNDEFINED_SYM
|
||||||
%token UNDERSCORE_CHARSET
|
%token UNDERSCORE_CHARSET
|
||||||
|
@ -1649,6 +1668,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token WEIGHT_STRING_SYM
|
%token WEIGHT_STRING_SYM
|
||||||
%token WHEN_SYM /* SQL-2003-R */
|
%token WHEN_SYM /* SQL-2003-R */
|
||||||
%token WHERE /* SQL-2003-R */
|
%token WHERE /* SQL-2003-R */
|
||||||
|
%token WINDOW_SYM
|
||||||
%token WHILE_SYM
|
%token WHILE_SYM
|
||||||
%token WITH /* SQL-2003-R */
|
%token WITH /* SQL-2003-R */
|
||||||
%token WITH_CUBE_SYM /* INTERNAL */
|
%token WITH_CUBE_SYM /* INTERNAL */
|
||||||
|
@ -1787,6 +1807,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
simple_ident_nospvar simple_ident_q
|
simple_ident_nospvar simple_ident_q
|
||||||
field_or_var limit_option
|
field_or_var limit_option
|
||||||
part_func_expr
|
part_func_expr
|
||||||
|
window_func_expr
|
||||||
|
window_func
|
||||||
|
simple_window_func
|
||||||
function_call_keyword
|
function_call_keyword
|
||||||
function_call_nonkeyword
|
function_call_nonkeyword
|
||||||
function_call_generic
|
function_call_generic
|
||||||
|
@ -1975,6 +1998,15 @@ END_OF_INPUT
|
||||||
%type <cond_info_item_name> condition_information_item_name;
|
%type <cond_info_item_name> condition_information_item_name;
|
||||||
%type <cond_info_list> condition_information;
|
%type <cond_info_list> condition_information;
|
||||||
|
|
||||||
|
%type <NONE> opt_window_clause window_def_list window_def window_spec
|
||||||
|
%type <lex_str_ptr> window_name
|
||||||
|
%type <NONE> opt_window_ref opt_window_frame_clause
|
||||||
|
%type <frame_units> window_frame_units;
|
||||||
|
%type <NONE> window_frame_extent;
|
||||||
|
%type <frame_exclusion> opt_window_frame_exclusion;
|
||||||
|
%type <window_frame_bound> window_frame_start window_frame_bound;
|
||||||
|
|
||||||
|
|
||||||
%type <NONE>
|
%type <NONE>
|
||||||
'-' '+' '*' '/' '%' '(' ')'
|
'-' '+' '*' '/' '%' '(' ')'
|
||||||
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
|
',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
|
||||||
|
@ -8497,6 +8529,7 @@ table_expression:
|
||||||
opt_where_clause
|
opt_where_clause
|
||||||
opt_group_clause
|
opt_group_clause
|
||||||
opt_having_clause
|
opt_having_clause
|
||||||
|
opt_window_clause
|
||||||
opt_order_clause
|
opt_order_clause
|
||||||
opt_limit_clause
|
opt_limit_clause
|
||||||
opt_procedure_clause
|
opt_procedure_clause
|
||||||
|
@ -9221,6 +9254,7 @@ simple_expr:
|
||||||
| param_marker { $$= $1; }
|
| param_marker { $$= $1; }
|
||||||
| variable
|
| variable
|
||||||
| sum_expr
|
| sum_expr
|
||||||
|
| window_func_expr
|
||||||
| simple_expr OR_OR_SYM simple_expr
|
| simple_expr OR_OR_SYM simple_expr
|
||||||
{
|
{
|
||||||
$$= new (thd->mem_root) Item_func_concat(thd, $1, $3);
|
$$= new (thd->mem_root) Item_func_concat(thd, $1, $3);
|
||||||
|
@ -10356,6 +10390,81 @@ sum_expr:
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
window_func_expr:
|
||||||
|
window_func OVER_SYM window_name
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1, $3);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
window_func OVER_SYM window_spec
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
if (Select->add_window_spec(thd, lex->win_ref,
|
||||||
|
Select->group_list,
|
||||||
|
Select->order_list,
|
||||||
|
lex->win_frame))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
$$= new (thd->mem_root) Item_window_func(thd, (Item_sum *) $1,
|
||||||
|
thd->lex->win_spec);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
window_func:
|
||||||
|
simple_window_func
|
||||||
|
|
|
||||||
|
sum_expr
|
||||||
|
;
|
||||||
|
|
||||||
|
simple_window_func:
|
||||||
|
ROW_NUMBER_SYM '(' ')'
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root) Item_sum_row_number(thd);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
RANK_SYM '(' ')'
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root) Item_sum_rank(thd);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
DENSE_RANK_SYM '(' ')'
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root) Item_sum_dense_rank(thd);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
PERCENT_RANK_SYM '(' ')'
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root) Item_sum_percent_rank(thd);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
CUME_DIST_SYM '(' ')'
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root) Item_sum_cume_dist(thd);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
window_name:
|
||||||
|
ident
|
||||||
|
{
|
||||||
|
$$= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING));
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
variable:
|
variable:
|
||||||
'@'
|
'@'
|
||||||
{
|
{
|
||||||
|
@ -11289,6 +11398,155 @@ olap_opt:
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
optional window clause in select
|
||||||
|
*/
|
||||||
|
|
||||||
|
opt_window_clause:
|
||||||
|
/* empty */
|
||||||
|
{}
|
||||||
|
| WINDOW_SYM
|
||||||
|
window_def_list
|
||||||
|
{}
|
||||||
|
;
|
||||||
|
|
||||||
|
window_def_list:
|
||||||
|
window_def_list ',' window_def
|
||||||
|
| window_def
|
||||||
|
;
|
||||||
|
|
||||||
|
window_def:
|
||||||
|
window_name AS window_spec
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
if (Select->add_window_def(thd, $1, lex->win_ref,
|
||||||
|
Select->group_list,
|
||||||
|
Select->order_list,
|
||||||
|
lex->win_frame ))
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
window_spec:
|
||||||
|
'('
|
||||||
|
{ Select->prepare_add_window_spec(thd); }
|
||||||
|
opt_window_ref opt_window_partition_clause
|
||||||
|
opt_window_order_clause opt_window_frame_clause
|
||||||
|
')'
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_window_ref:
|
||||||
|
/* empty */ {}
|
||||||
|
| ident
|
||||||
|
{
|
||||||
|
thd->lex->win_ref= (LEX_STRING *) thd->memdup(&$1, sizeof(LEX_STRING));
|
||||||
|
if (thd->lex->win_ref == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_window_partition_clause:
|
||||||
|
/* empty */ { }
|
||||||
|
| PARTITION_SYM BY group_list
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_window_order_clause:
|
||||||
|
/* empty */ { }
|
||||||
|
| ORDER_SYM BY order_list
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_window_frame_clause:
|
||||||
|
/* empty */ {}
|
||||||
|
| window_frame_units window_frame_extent opt_window_frame_exclusion
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->win_frame=
|
||||||
|
new (thd->mem_root) Window_frame($1,
|
||||||
|
lex->frame_top_bound,
|
||||||
|
lex->frame_bottom_bound,
|
||||||
|
$3);
|
||||||
|
if (lex->win_frame == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
window_frame_units:
|
||||||
|
ROWS_SYM { $$= Window_frame::UNITS_ROWS; }
|
||||||
|
| RANGE_SYM { $$= Window_frame::UNITS_RANGE; }
|
||||||
|
;
|
||||||
|
|
||||||
|
window_frame_extent:
|
||||||
|
window_frame_start
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->frame_top_bound= $1;
|
||||||
|
lex->frame_bottom_bound=
|
||||||
|
new (thd->mem_root)
|
||||||
|
Window_frame_bound(Window_frame_bound::CURRENT, NULL);
|
||||||
|
if (lex->frame_bottom_bound == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| BETWEEN_SYM window_frame_bound AND_SYM window_frame_bound
|
||||||
|
{
|
||||||
|
LEX *lex= Lex;
|
||||||
|
lex->frame_top_bound= $2;
|
||||||
|
lex->frame_bottom_bound= $4;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
window_frame_start:
|
||||||
|
UNBOUNDED_SYM PRECEDING_SYM
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root)
|
||||||
|
Window_frame_bound(Window_frame_bound::PRECEDING, NULL);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| CURRENT_SYM ROW_SYM
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root)
|
||||||
|
Window_frame_bound(Window_frame_bound::CURRENT, NULL);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| literal PRECEDING_SYM
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root)
|
||||||
|
Window_frame_bound(Window_frame_bound::PRECEDING, $1);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
window_frame_bound:
|
||||||
|
window_frame_start { $$= $1; }
|
||||||
|
| UNBOUNDED_SYM FOLLOWING_SYM
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root)
|
||||||
|
Window_frame_bound(Window_frame_bound::FOLLOWING, NULL);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
| literal FOLLOWING_SYM
|
||||||
|
{
|
||||||
|
$$= new (thd->mem_root)
|
||||||
|
Window_frame_bound(Window_frame_bound::FOLLOWING, $1);
|
||||||
|
if ($$ == NULL)
|
||||||
|
MYSQL_YYABORT;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
opt_window_frame_exclusion:
|
||||||
|
/* empty */ { $$= Window_frame::EXCL_NONE; }
|
||||||
|
| EXCLUDE_SYM CURRENT_SYM ROW_SYM
|
||||||
|
{ $$= Window_frame::EXCL_CURRENT_ROW; }
|
||||||
|
| EXCLUDE_SYM GROUP_SYM
|
||||||
|
{ $$= Window_frame::EXCL_GROUP; }
|
||||||
|
| EXCLUDE_SYM TIES_SYM
|
||||||
|
{ $$= Window_frame::EXCL_TIES; }
|
||||||
|
| EXCLUDE_SYM NO_SYM OTHERS_SYM
|
||||||
|
{ $$= Window_frame::EXCL_NONE; }
|
||||||
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Order by statement in ALTER TABLE
|
Order by statement in ALTER TABLE
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue