diff options
-rw-r--r-- | sql/Makefile.am | 2 | ||||
-rw-r--r-- | sql/lex.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 12 | ||||
-rw-r--r-- | sql/sql_parse.cc | 3 | ||||
-rw-r--r-- | sql/sql_select.cc | 19 | ||||
-rw-r--r-- | sql/sql_union.cc | 8 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 25 | ||||
-rw-r--r-- | sql/table.h | 1 |
8 files changed, 64 insertions, 8 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am index e1ed9ad8915..55945583967 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -81,7 +81,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc sql_union.cc \ mini_client.cc mini_client_errors.c \ - stacktrace.c repl_failsafe.h repl_failsafe.cc + stacktrace.c repl_failsafe.h repl_failsafe.cc sql_olap.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/lex.h b/sql/lex.h index 81d597c6a5c..c44cef05215 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -98,6 +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}, { "CURRENT_DATE", SYM(CURDATE),0,0}, { "CURRENT_TIME", SYM(CURTIME),0,0}, { "CURRENT_TIMESTAMP", SYM(NOW_SYM),0,0}, @@ -303,6 +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}, { "ROW", SYM(ROW_SYM),0,0}, { "ROWS", SYM(ROWS_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0}, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 88dadcca5a4..593f1a39ea5 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -89,7 +89,12 @@ typedef struct st_lex_master_info enum sub_select_type { - UNSPECIFIED_TYPE, UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, NOT_A_SELECT + UNSPECIFIED_TYPE, UNION_TYPE, INTERSECT_TYPE, EXCEPT_TYPE, OLAP_TYPE, NOT_A_SELECT +}; + +enum olap_type +{ + NON_EXISTING_ONE, CUBE_TYPE, ROLLUP_TYPE }; /* The state of the lex parsing for selects */ @@ -97,6 +102,7 @@ enum sub_select_type typedef struct st_select_lex { enum sub_select_type linkage; + enum olap_type olap; char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */ Item *where,*having; ha_rows select_limit,offset_limit; @@ -133,7 +139,7 @@ typedef struct st_lex { uint yylineno,yytoklen; /* Simulate lex */ LEX_YYSTYPE yylval; - SELECT_LEX select_lex, *select; + SELECT_LEX select_lex, *select, *last_selects; uchar *ptr,*tok_start,*tok_end,*end_of_query; char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ @@ -178,7 +184,7 @@ typedef struct st_lex uint grant,grant_tot_col,which_columns, union_option; thr_lock_type lock_option; bool drop_primary,drop_if_exists,local_file; - bool in_comment,ignore_space,verbose,simple_alter, option_type; + bool in_comment,ignore_space,verbose,simple_alter, option_type, olap; uint slave_thd_opt; } LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index df44a7e043f..f4bb881bf8d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2728,7 +2728,9 @@ mysql_init_select(LEX *lex) select_lex->offset_limit=0; select_lex->options=0; 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; @@ -3270,6 +3272,7 @@ static bool create_total_list(THD *thd, LEX *lex, TABLE_LIST **result) for (; aux; aux=next) { TABLE_LIST *cursor; + aux->do_redirect=true; next= aux->next; for (cursor= *result; cursor; cursor=cursor->next) if (!strcmp(cursor->db,aux->db) && diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 459c85a4108..9eb11678de8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -146,7 +146,7 @@ static bool update_sum_func(Item_sum **func); static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, bool distinct, const char *message=NullS); static void describe_info(JOIN *join, const char *info); - +extern int handle_olaps(LEX *lex, SELECT_LEX *select); /* This handles SELECT with and without UNION */ @@ -155,6 +155,23 @@ int handle_select(THD *thd, LEX *lex, select_result *result) { int res; register SELECT_LEX *select_lex = &lex->select_lex; + if (lex->olap) + { + SELECT_LEX *sl, *last_sl; + int returned; + for (sl= &lex->select_lex;sl;sl=sl->next) + { + if (sl->olap != NON_EXISTING_ONE) + { + last_sl=sl->next; + if ((returned=handle_olaps(lex,sl))) + return returned; + lex->last_selects->next=sl=last_sl; + if (!sl) break; + } + } + lex->select = select_lex; + } if (select_lex->next) res=mysql_union(thd,lex,result); else diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 983ff44dc73..f25a6e57315 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -49,7 +49,13 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first; cursor; cursor=cursor->next) - cursor->table= ((TABLE_LIST*) cursor->table)->table; + { + if (cursor->do_redirect) + { + cursor->table= ((TABLE_LIST*) cursor->table)->table; + cursor->do_redirect=false; + } + } } /* last_sel now points at the last select where the ORDER BY is stored */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 635896c2ab2..fbfa42c0b5e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -109,6 +109,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token COUNT_SYM %token CREATE %token CROSS +%token CUBE %token DELETE_SYM %token DO_SYM %token DROP @@ -130,6 +131,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token REPLICATION %token RESET_SYM %token ROLLBACK_SYM +%token ROLLUP %token SELECT_SYM %token SHOW %token SLAVE @@ -2160,7 +2162,7 @@ opt_escape: group_clause: /* empty */ - | GROUP BY group_list; + | GROUP BY group_list olap_opt; group_list: group_list ',' order_ident order_dir @@ -2168,6 +2170,19 @@ group_list: | order_ident order_dir { if (add_group_to_list($1,(bool) $2)) YYABORT; }; +olap_opt: + /* empty */ {} + | WITH CUBE + { + Lex->olap = true; + Select->olap= CUBE_TYPE; + } + | WITH ROLLUP + { + Lex->olap = true; + Select->olap= ROLLUP_TYPE; + } + /* Order by statement in select */ @@ -2180,7 +2195,7 @@ order_clause: ORDER_SYM BY { LEX *lex=Lex; - if (lex->sql_command == SQLCOM_MULTI_UPDATE) + if (lex->sql_command == SQLCOM_MULTI_UPDATE || lex->olap) YYABORT; lex->select->sort_default=1; } order_list; @@ -2201,12 +2216,16 @@ limit_clause: /* empty */ {} | LIMIT ULONG_NUM { + if (Lex->olap) + YYABORT; SELECT_LEX *sel=Select; sel->select_limit= $2; sel->offset_limit=0L; } | LIMIT ULONG_NUM ',' ULONG_NUM { + if (Lex->olap) + YYABORT; SELECT_LEX *sel=Select; sel->select_limit= $4; sel->offset_limit=$2; }; @@ -3011,6 +3030,7 @@ keyword: | COMMIT_SYM {} | COMPRESSED_SYM {} | CONCURRENT {} + | CUBE {} | DATA_SYM {} | DATETIME {} | DATE_SYM {} @@ -3104,6 +3124,7 @@ keyword: | RESOURCES {} | RESTORE_SYM {} | ROLLBACK_SYM {} + | ROLLUP {} | ROWS_SYM {} | ROW_FORMAT_SYM {} | ROW_SYM {} diff --git a/sql/table.h b/sql/table.h index 63b7a9bc2f7..229d41a2df7 100644 --- a/sql/table.h +++ b/sql/table.h @@ -151,6 +151,7 @@ typedef struct st_table_list bool straight; /* optimize with prev table */ bool updating; /* for replicate-do/ignore table */ bool shared; /* Used twice in union */ + bool do_redirect; /* To get the struct in UNION's */ } TABLE_LIST; |