diff options
author | Michael Widenius <monty@askmonty.org> | 2012-09-09 00:38:15 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-09-09 00:38:15 +0300 |
commit | 5161b3ddde41617cc623e54980f6f28f38e650a7 (patch) | |
tree | 8da35de47ecc339e7d3e7642c59bab2e4ef17546 | |
parent | 22de18ddcb97640f8f90c1c88d1dcd795ba1070f (diff) | |
parent | 2fc4c75194c1c6cc432d847ed47ef73298ff4c7f (diff) | |
download | mariadb-git-5161b3ddde41617cc623e54980f6f28f38e650a7.tar.gz |
Automatic merge
-rw-r--r-- | client/mysql.cc | 1 | ||||
-rw-r--r-- | mysql-test/r/last_value.result | 73 | ||||
-rw-r--r-- | mysql-test/t/last_value.test | 43 | ||||
-rw-r--r-- | sql/derror.cc | 4 | ||||
-rw-r--r-- | sql/item_func.cc | 59 | ||||
-rw-r--r-- | sql/item_func.h | 21 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/mysqld.cc | 24 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 8 |
9 files changed, 220 insertions, 14 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index d39e765a99a..5aab3e1098f 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -897,6 +897,7 @@ static COMMANDS commands[] = { { "LAST_INSERT_ID", 0, 0, 0, ""}, { "ISSIMPLE", 0, 0, 0, ""}, { "LAST_DAY", 0, 0, 0, ""}, + { "LAST_VALUE", 0, 0, 0, ""}, { "LCASE", 0, 0, 0, ""}, { "LEAST", 0, 0, 0, ""}, { "LENGTH", 0, 0, 0, ""}, diff --git a/mysql-test/r/last_value.result b/mysql-test/r/last_value.result new file mode 100644 index 00000000000..6222eacd4f0 --- /dev/null +++ b/mysql-test/r/last_value.result @@ -0,0 +1,73 @@ +drop table if exists t1; +drop database if exists mysqltest; +CREATE TABLE t1 (a INT, b INT, c INT, d INT); +INSERT INTO t1 VALUES (1,3,0,NULL),(2,2,0,NULL),(3,4,0,NULL),(4,2,0,NULL); +SELECT * FROM t1; +a b c d +1 3 0 NULL +2 2 0 NULL +3 4 0 NULL +4 2 0 NULL +UPDATE t1 SET c=LAST_VALUE(@last_a:=a,@last_b:=b,@last_c:=c,1), d=4211 WHERE c=0 ORDER BY b DESC LIMIT 1; +SELECT @last_a, @last_b, @last_c; +@last_a @last_b @last_c +3 4 0 +SELECT * FROM t1; +a b c d +1 3 0 NULL +2 2 0 NULL +3 4 1 4211 +4 2 0 NULL +DROP TABLE t1; +SELECT LAST_VALUE(@last_a:=1,@last_b:=1); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def LAST_VALUE(@last_a:=1,@last_b:=1) 8 1 1 N 32897 0 63 +LAST_VALUE(@last_a:=1,@last_b:=1) +1 +select @last_b; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def @last_b 8 20 1 Y 32896 0 63 +@last_b +1 +SELECT LAST_VALUE(@last_a:=1,@last_b:=1.0); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def LAST_VALUE(@last_a:=1,@last_b:=1.0) 246 4 3 N 32897 1 63 +LAST_VALUE(@last_a:=1,@last_b:=1.0) +1.0 +select @last_b; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def @last_b 246 83 3 Y 32896 30 63 +@last_b +1.0 +SELECT LAST_VALUE(@last_a:=1,@last_b:="hello"); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def LAST_VALUE(@last_a:=1,@last_b:="hello") 253 5 5 N 1 31 8 +LAST_VALUE(@last_a:=1,@last_b:="hello") +hello +select @last_b; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def @last_b 250 16777215 5 Y 0 31 8 +@last_b +hello +SELECT date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03")); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03")) 10 10 10 Y 128 0 63 +date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03")) +2001-02-03 +select @last_b; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def @last_b 250 16777215 10 Y 0 31 8 +@last_b +2001-02-03 +SELECT LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL) 6 0 0 Y 32896 0 63 +LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL) +NULL +select @last_b; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def @last_b 250 16777215 10 Y 0 31 8 +@last_b +2001-02-03 +SELECT LAST_VALUE(); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 diff --git a/mysql-test/t/last_value.test b/mysql-test/t/last_value.test new file mode 100644 index 00000000000..ee793f879da --- /dev/null +++ b/mysql-test/t/last_value.test @@ -0,0 +1,43 @@ +# +# Tests for the LAST_VALUE function +# + +--disable_warnings +drop table if exists t1; +drop database if exists mysqltest; +--enable_warnings + +# CREATE TABLE `queue` ( +# `id` int(10) unsigned NOT NULL AUTO_INCREMENT, +# `priority` int(11) DEFAULT NULL, +# `state` int(11) DEFAULT NULL, +# `pid` int(10) unsigned DEFAULT NULL, +# `dat` varbinary(200) DEFAULT NULL, +# PRIMARY KEY (`id`) +# ) + +CREATE TABLE t1 (a INT, b INT, c INT, d INT); +INSERT INTO t1 VALUES (1,3,0,NULL),(2,2,0,NULL),(3,4,0,NULL),(4,2,0,NULL); +SELECT * FROM t1; +UPDATE t1 SET c=LAST_VALUE(@last_a:=a,@last_b:=b,@last_c:=c,1), d=4211 WHERE c=0 ORDER BY b DESC LIMIT 1; +SELECT @last_a, @last_b, @last_c; +SELECT * FROM t1; +DROP TABLE t1; + +# +# Test with different types +# +--enable_metadata +SELECT LAST_VALUE(@last_a:=1,@last_b:=1); +select @last_b; +SELECT LAST_VALUE(@last_a:=1,@last_b:=1.0); +select @last_b; +SELECT LAST_VALUE(@last_a:=1,@last_b:="hello"); +select @last_b; +SELECT date(LAST_VALUE(@last_a:=1,@last_b:="2001-02-03")); +select @last_b; +SELECT LAST_VALUE(@last_a:=1,@last_b:="2001-02-03",NULL); +select @last_b; +--disable_metadata +--error ER_PARSE_ERROR +SELECT LAST_VALUE(); diff --git a/sql/derror.cc b/sql/derror.cc index baf7163790d..33835992258 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -177,8 +177,8 @@ bool read_texts(const char *file_name, const char *language, O_RDONLY | O_SHARE | O_BINARY, MYF(0))) < 0) goto err; - sql_print_error("An old style --language value with language specific part detected: %s", lc_messages_dir); - sql_print_error("Use --lc-messages-dir without language specific part instead."); + sql_print_warning("An old style --language or -lc-message-dir value with language specific part detected: %s", lc_messages_dir); + sql_print_warning("Use --lc-messages-dir without language specific part instead."); } funktpos=1; diff --git a/sql/item_func.cc b/sql/item_func.cc index 7a7cdd4ba02..1e891f06f0b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6816,3 +6816,62 @@ longlong Item_func_uuid_short::val_int() mysql_mutex_unlock(&LOCK_short_uuid_generator); return (longlong) val; } + + +/** + Last_value - return last argument. +*/ + +void Item_func_last_value::evaluate_sideeffects() +{ + DBUG_ASSERT(fixed == 1 && arg_count > 0); + for (uint i= 0; i < arg_count-1 ; i++) + args[i]->val_int(); +} + +String *Item_func_last_value::val_str(String *str) +{ + String *tmp; + evaluate_sideeffects(); + tmp= last_value->val_str(str); + null_value= last_value->null_value; + return tmp; +} + +longlong Item_func_last_value::val_int() +{ + longlong tmp; + evaluate_sideeffects(); + tmp= last_value->val_int(); + null_value= last_value->null_value; + return tmp; +} + +double Item_func_last_value::val_real() +{ + double tmp; + evaluate_sideeffects(); + tmp= last_value->val_real(); + null_value= last_value->null_value; + return tmp; +} + +my_decimal *Item_func_last_value::val_decimal(my_decimal *decimal_value) +{ + my_decimal *tmp; + evaluate_sideeffects(); + tmp= last_value->val_decimal(decimal_value); + null_value= last_value->null_value; + return tmp; +} + + +void Item_func_last_value::fix_length_and_dec() +{ + last_value= args[arg_count -1]; + decimals= last_value->decimals; + max_length= last_value->max_length; + collation.set(last_value->collation.collation); + maybe_null= last_value->maybe_null; + unsigned_flag= last_value->unsigned_flag; +} diff --git a/sql/item_func.h b/sql/item_func.h index 111479c8e52..586444e0e4e 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -2003,6 +2003,27 @@ public: } }; + +class Item_func_last_value :public Item_func +{ +protected: + Item *last_value; +public: + Item_func_last_value(List<Item> &list) :Item_func(list) {} + double val_real(); + longlong val_int(); + String *val_str(String *); + my_decimal *val_decimal(my_decimal *); + void fix_length_and_dec(); + enum Item_result result_type () const { return last_value->result_type(); } + const char *func_name() const { return "last_value"; } + table_map not_null_tables() const { return 0; } + enum_field_types field_type() const { return last_value->field_type(); } + bool const_item() const { return 0; } + void evaluate_sideeffects(); +}; + + Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, LEX_STRING component); extern bool check_reserved_words(LEX_STRING *name); diff --git a/sql/lex.h b/sql/lex.h index 9f4369630a0..9bf4c439cb6 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -302,6 +302,7 @@ static SYMBOL symbols[] = { { "KILL", SYM(KILL_SYM)}, { "LANGUAGE", SYM(LANGUAGE_SYM)}, { "LAST", SYM(LAST_SYM)}, + { "LAST_VALUE", SYM(LAST_VALUE)}, { "LEADING", SYM(LEADING)}, { "LEAVE", SYM(LEAVE_SYM)}, { "LEAVES", SYM(LEAVES)}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 47be8551359..c2a07e11f0e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -360,7 +360,7 @@ static DYNAMIC_ARRAY all_options; /* Global variables */ -bool opt_bin_log, opt_ignore_builtin_innodb= 0; +bool opt_bin_log, opt_bin_log_used=0, opt_ignore_builtin_innodb= 0; my_bool opt_log, opt_slow_log, debug_assert_if_crashed_table= 0, opt_help= 0, opt_abort; ulonglong log_output_options; my_bool opt_userstat_running; @@ -579,7 +579,7 @@ char mysql_real_data_home[FN_REFLEN], lc_messages_dir[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN], *opt_init_file, *opt_tc_log_file; -char *lc_messages_dir_ptr, *log_error_file_ptr; +char *lc_messages_dir_ptr= lc_messages_dir, *log_error_file_ptr; char mysql_unpacked_real_data_home[FN_REFLEN]; int mysql_unpacked_real_data_home_len; uint mysql_real_data_home_len, mysql_data_home_len= 1; @@ -4172,14 +4172,15 @@ static int init_server_components() unireg_abort(1); /* need to configure logging before initializing storage engines */ - if (opt_log_slave_updates && !opt_bin_log) + if (!opt_bin_log_used) { - sql_print_warning("You need to use --log-bin to make " - "--log-slave-updates work."); + if (opt_log_slave_updates) + sql_print_warning("You need to use --log-bin to make " + "--log-slave-updates work."); + if (binlog_format_used) + sql_print_warning("You need to use --log-bin to make " + "--binlog-format work."); } - if (!opt_bin_log && binlog_format_used) - sql_print_warning("You need to use --log-bin to make " - "--binlog-format work."); /* Check that we have not let the format to unspecified at this point */ DBUG_ASSERT((uint)global_system_variables.binlog_format <= @@ -6226,7 +6227,7 @@ struct my_option my_long_options[]= {"language", 'L', "Client error messages in given language. May be given as a full path. " "Deprecated. Use --lc-messages-dir instead.", - &lc_messages_dir_ptr, &lc_messages_dir_ptr, 0, + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"lc-messages", 0, "Set the language used for the error messages.", @@ -7218,7 +7219,7 @@ static int mysql_init_variables(void) myisam_test_invalid_symlink= test_if_data_home_dir; #endif opt_log= opt_slow_log= 0; - opt_bin_log= 0; + opt_bin_log= opt_bin_log_used= 0; opt_disable_networking= opt_skip_show_db=0; opt_skip_name_resolve= 0; opt_ignore_builtin_innodb= 0; @@ -7270,7 +7271,6 @@ static int mysql_init_variables(void) mysql_home_ptr= mysql_home; pidfile_name_ptr= pidfile_name; log_error_file_ptr= log_error_file; - lc_messages_dir_ptr= lc_messages_dir; protocol_version= PROTOCOL_VERSION; what_to_log= ~ (1L << (uint) COM_TIME); refresh_version= 1L; /* Increments on each reload */ @@ -7459,7 +7459,6 @@ mysqld_get_one_option(int optid, break; case 'L': strmake(lc_messages_dir, argument, sizeof(lc_messages_dir)-1); - lc_messages_dir_ptr= lc_messages_dir; break; case OPT_BINLOG_FORMAT: binlog_format_used= true; @@ -7488,6 +7487,7 @@ mysqld_get_one_option(int optid, break; case (int) OPT_BIN_LOG: opt_bin_log= test(argument != disabled_my_option); + opt_bin_log_used= 1; break; case (int) OPT_LOG_BASENAME: { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 220eeb5b9a7..555efaf366d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1064,6 +1064,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token KILL_SYM %token LANGUAGE_SYM /* SQL-2003-R */ %token LAST_SYM /* SQL-2003-N */ +%token LAST_VALUE %token LE /* OPERATOR */ %token LEADING /* SQL-2003-R */ %token LEAVES @@ -8890,6 +8891,12 @@ function_call_conflict: if ($$ == NULL) MYSQL_YYABORT; } + | LAST_VALUE '(' expr_list ')' + { + $$= new (YYTHD->mem_root) Item_func_last_value(* $3); + if ($$ == NULL) + MYSQL_YYABORT; + } | MICROSECOND_SYM '(' expr ')' { $$= new (YYTHD->mem_root) Item_func_microsecond($3); @@ -13088,6 +13095,7 @@ keyword_sp: | ISSUER_SYM {} | INSERT_METHOD {} | KEY_BLOCK_SIZE {} + | LAST_VALUE {} | LAST_SYM {} | LEAVES {} | LESS_SYM {} |