summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2012-09-05 18:23:51 +0300
committerMichael Widenius <monty@askmonty.org>2012-09-05 18:23:51 +0300
commitd618dfe32dfe004f3bfd6aa79a4fb96d1cc7999d (patch)
treeb0ce4ecfef749a529289a3e7a74192303bd67bb1 /sql
parent5620937c058aa9f7cd3b122b40f8b9c94fa69997 (diff)
downloadmariadb-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.cc59
-rw-r--r--sql/item_func.h21
-rw-r--r--sql/lex.h1
-rw-r--r--sql/sql_yacc.yy8
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 {}