diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index f649231e247..b42fbc64c53 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -45,7 +45,10 @@ nick@nick.leippe.com paul@central.snake.net paul@teton.kitebird.com peter@linux.local +peter@mysql.com root@x3.internalnet +salle@geopard.(none) +salle@geopard.online.bg sasha@mysql.sashanet.com serg@serg.mysql.com serg@sergbook.mysql.com @@ -64,10 +67,8 @@ tonu@volk.internalnet tonu@x153.internalnet tonu@x3.internalnet venu@work.mysql.com +walrus@mysql.com worm@altair.is.lan zak@balfor.local zak@linux.local -salle@geopard.(none) -walrus@mysql.com zgreant@mysql.com -salle@geopard.online.bg diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index f067d1f651e..f1c0de2f88a 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -16,9 +16,18 @@ round(5.64,1) round(5.64,2) round(5.64,-1) round(5.64,-2) select abs(-10), sign(-5), sign(5), sign(0); abs(-10) sign(-5) sign(5) sign(0) 10 -1 1 0 -select log(exp(10)),exp(log(sqrt(10))*2); -log(exp(10)) exp(log(sqrt(10))*2) -10.000000 10.000000 +select log(exp(10)),exp(log(sqrt(10))*2),log(-1),log(NULL),log(1,1),log(3,9),log(-1,2),log(NULL,2); +log(exp(10)) exp(log(sqrt(10))*2) log(-1) log(NULL) log(1,1) log(3,9) log(-1,2) log(NULL,2) +10.000000 10.000000 NULL NULL NULL 2.000000 NULL NULL +select ln(exp(10)),exp(ln(sqrt(10))*2),ln(-1),ln(0),ln(NULL); +ln(exp(10)) exp(ln(sqrt(10))*2) ln(-1) ln(0) ln(NULL) +10.000000 10.000000 NULL NULL NULL +select log2(8),log2(15),log2(-2),log2(0),log2(NULL); +log2(8) log2(15) log2(-2) log2(0) log2(NULL) +3.000000 3.906891 NULL NULL NULL +select log10(100),log10(18),log10(-4),log10(0),log10(NULL); +log10(100) log10(18) log10(-4) log10(0) log10(NULL) +2.000000 1.255273 NULL NULL NULL select pow(10,log10(10)),power(2,4); pow(10,log10(10)) power(2,4) 10.000000 16.000000 diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 5299897d0f0..74e8a5ce092 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -8,7 +8,10 @@ select truncate(52.64,1),truncate(52.64,2),truncate(52.64,-1),truncate(52.64,-2) select round(5.5),round(-5.5); select round(5.64,1),round(5.64,2),round(5.64,-1),round(5.64,-2); select abs(-10), sign(-5), sign(5), sign(0); -select log(exp(10)),exp(log(sqrt(10))*2); +select log(exp(10)),exp(log(sqrt(10))*2),log(-1),log(NULL),log(1,1),log(3,9),log(-1,2),log(NULL,2); +select ln(exp(10)),exp(ln(sqrt(10))*2),ln(-1),ln(0),ln(NULL); +select log2(8),log2(15),log2(-2),log2(0),log2(NULL); +select log10(100),log10(18),log10(-4),log10(0),log10(NULL); select pow(10,log10(10)),power(2,4); select rand(999999),rand(); select pi(),sin(pi()/2),cos(pi()/2),abs(tan(pi())),cot(1),asin(1),acos(0),atan(1); diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 776b6840b45..c61a75ab880 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -74,13 +74,13 @@ static struct my_option my_long_options[] = {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"rnd1", 'r', "Set 1 part of rnd value for hash generator", - (gptr*) &best_t1, (gptr*) &best_t1, 0, GET_ULONG, REQUIRED_ARG, 6657025L, + (gptr*) &best_t1, (gptr*) &best_t1, 0, GET_ULONG, REQUIRED_ARG, 5075635L, 0, 0, 0, 0, 0}, {"rnd2", 'R', "Set 2 part of rnd value for hash generator", - (gptr*) &best_t2, (gptr*) &best_t2, 0, GET_ULONG, REQUIRED_ARG, 6114496L, + (gptr*) &best_t2, (gptr*) &best_t2, 0, GET_ULONG, REQUIRED_ARG, 1345933L, 0, 0, 0, 0, 0}, {"type", 't', "Set type of char table to generate", - (gptr*) &best_type, (gptr*) &best_type, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, + (gptr*) &best_type, (gptr*) &best_type, 0, GET_UINT, REQUIRED_ARG, 4, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -479,7 +479,7 @@ int main(int argc,char **argv) MY_INIT(argv[0]); - start_value=1109118L; /* mode=4903 add=3 type: 0 */ + start_value=3807640L; /* mode=6971 add=3 type: 0 */ if (get_options(argc,(char **) argv)) exit(1); diff --git a/sql/item_create.cc b/sql/item_create.cc index 62f09f002d1..e75c7049a74 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -220,9 +220,14 @@ Item *create_func_char_length(Item* a) return new Item_func_char_length(a); } -Item *create_func_log(Item* a) +Item *create_func_ln(Item* a) { - return new Item_func_log(a); + return new Item_func_ln(a); +} + +Item *create_func_log2(Item* a) +{ + return new Item_func_log2(a); } Item *create_func_log10(Item* a) diff --git a/sql/item_create.h b/sql/item_create.h index 967de0e2eba..730a1510988 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -52,8 +52,9 @@ Item *create_func_instr(Item* a, Item *b); Item *create_func_isnull(Item* a); Item *create_func_lcase(Item* a); Item *create_func_length(Item* a); +Item *create_func_ln(Item* a); Item *create_func_locate(Item* a, Item *b); -Item *create_func_log(Item* a); +Item *create_func_log2(Item* a); Item *create_func_log10(Item* a); Item *create_func_lpad(Item* a, Item *b, Item *c); Item *create_func_ltrim(Item* a); diff --git a/sql/item_func.cc b/sql/item_func.cc index 4ec4377509f..807f023b308 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -437,14 +437,43 @@ void Item_func_abs::fix_length_and_dec() hybrid_type= args[0]->result_type() == INT_RESULT ? INT_RESULT : REAL_RESULT; } +/* Gateway to natural LOG function */ +double Item_func_ln::val() +{ + double value=args[0]->val(); + if ((null_value=(args[0]->null_value || value <= 0.0))) + return 0.0; + return log(value); +} + +/* + Extended but so slower LOG function + We have to check if all values are > zero and first one is not one + as these are the cases then result is not a number. +*/ double Item_func_log::val() { double value=args[0]->val(); if ((null_value=(args[0]->null_value || value <= 0.0))) - return 0.0; /* purecov: inspected */ + return 0.0; + if (arg_count == 2) + { + double value2= args[1]->val(); + if ((null_value=(args[1]->null_value || value2 <= 0.0 || value == 1.0))) + return 0.0; + return log(value2) / log(value); + } return log(value); } +double Item_func_log2::val() +{ + double value=args[0]->val(); + if ((null_value=(args[0]->null_value || value <= 0.0))) + return 0.0; + return log(value) / log(2.0); +} + double Item_func_log10::val() { double value=args[0]->val(); diff --git a/sql/item_func.h b/sql/item_func.h index 6ecbc04ddf0..184a5e5fbe9 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -342,15 +342,35 @@ public: const char *func_name() const { return "exp"; } }; + +class Item_func_ln :public Item_dec_func +{ +public: + Item_func_ln(Item *a) :Item_dec_func(a) {} + double val(); + const char *func_name() const { return "ln"; } +}; + + class Item_func_log :public Item_dec_func { public: Item_func_log(Item *a) :Item_dec_func(a) {} + Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {} double val(); const char *func_name() const { return "log"; } }; +class Item_func_log2 :public Item_dec_func +{ +public: + Item_func_log2(Item *a) :Item_dec_func(a) {} + double val(); + const char *func_name() const { return "log2"; } +}; + + class Item_func_log10 :public Item_dec_func { public: diff --git a/sql/lex.h b/sql/lex.h index 4f5d3c794ff..19b27034ce6 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -463,9 +463,11 @@ static SYMBOL sql_functions[] = { { "LCASE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, { "LEAST", SYM(LEAST_SYM),0,0}, { "LENGTH", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)}, + { "LN", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ln)}, { "LOAD_FILE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)}, { "LOCATE", SYM(LOCATE),0,0}, - { "LOG", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log)}, + { "LOG", SYM(LOG_SYM),0,0}, + { "LOG2", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log2)}, { "LOG10", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log10)}, { "LOWER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)}, { "LPAD", SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_lpad)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ced5a28b4f0..eaaadc70eab 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -233,6 +233,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token LIKE %token LINES %token LOCAL_SYM +%token LOG_SYM %token LOGS_SYM %token LONG_NUM %token LONG_SYM @@ -1781,6 +1782,10 @@ simple_expr: { $5->push_front($3); $$= new Item_func_max(*$5); } | LEAST_SYM '(' expr ',' expr_list ')' { $5->push_front($3); $$= new Item_func_min(*$5); } + | LOG_SYM '(' expr ')' + { $$= new Item_func_log($3); } + | LOG_SYM '(' expr ',' expr ')' + { $$= new Item_func_log($3, $5); } | MINUTE_SYM '(' expr ')' { $$= new Item_func_minute($3); } | MONTH_SYM '(' expr ')' diff --git a/tests/function.res b/tests/function.res index a2322020d74..acd34f41a3e 100644 --- a/tests/function.res +++ b/tests/function.res @@ -11,11 +11,11 @@ select floor(5.5),floor(-5.5),ceiling(5.5),ceiling(-5.5),round(5.5),round(-5.5) floor(5.5) floor(-5.5) ceiling(5.5) ceiling(-5.5) round(5.5) round(-5.5) 5 -6 6 -5 6 -6 -------------- -select abs(-10),log(exp(10)),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand() +select abs(-10),log(exp(10)),ln(exp(10)),log2(65535),log(2,65535),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand() -------------- -abs(-10) log(exp(10)) exp(log(sqrt(10))*2) pow(10,log10(10)) rand(999999) rand() -10 10.000000 10.000000 10.000000 0.1844 0.7637 +abs(-10) log(exp(10)) ln(exp(10)) log2(65535) log(2,65535) exp(log(sqrt(10))*2) pow(10,log10(10)) rand(999999) rand() +10 10.000000 10.000000 2.000000 2.000000 10.000000 10.000000 0.1844 0.7637 -------------- select least(6,1.0,2.0),greatest(3,4,5,0) -------------- diff --git a/tests/function.tst b/tests/function.tst index 5b8746e8d3c..17e1cb6c8ac 100644 --- a/tests/function.tst +++ b/tests/function.tst @@ -7,7 +7,7 @@ # select 1+1,1-1,1+1*2,8/5,8%5,mod(8,5),mod(8,5)|0,-(1+1)*-2,sign(-5) ; select floor(5.5),floor(-5.5),ceiling(5.5),ceiling(-5.5),round(5.5),round(-5.5); -select abs(-10),log(exp(10)),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand(); +select abs(-10),log(exp(10)),ln(exp(10)),log2(65535),log(2,65535),exp(log(sqrt(10))*2),pow(10,log10(10)),rand(999999),rand(); select least(6,1.0,2.0),greatest(3,4,5,0) ; select 1 | (1+1),5 & 3,bit_count(7) ; #