diff options
author | Michael Widenius <monty@askmonty.org> | 2012-09-05 18:23:51 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2012-09-05 18:23:51 +0300 |
commit | d618dfe32dfe004f3bfd6aa79a4fb96d1cc7999d (patch) | |
tree | b0ce4ecfef749a529289a3e7a74192303bd67bb1 /sql | |
parent | 5620937c058aa9f7cd3b122b40f8b9c94fa69997 (diff) | |
download | mariadb-git-d618dfe32dfe004f3bfd6aa79a4fb96d1cc7999d.tar.gz |
Added function last_value() which returns the last value but evalutes all arguments as a side effect.
Original patch by Eric Herman
client/mysql.cc:
Added LAST_VALUE
mysql-test/r/last_value.result:
Testing of LAST_VALUE
mysql-test/t/last_value.test:
Testing of LAST_VALUE
sql/item_func.cc:
Added LAST_VALUE()
sql/item_func.h:
Added LAST_VALUE()
sql/lex.h:
Added LAST_VALUE()
sql/sql_yacc.yy:
Added LAST_VALUE()
Diffstat (limited to 'sql')
-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/sql_yacc.yy | 8 |
4 files changed, 89 insertions, 0 deletions
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/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 {} |