diff options
author | unknown <peter@mysql.com> | 2002-07-17 12:11:48 +0400 |
---|---|---|
committer | unknown <peter@mysql.com> | 2002-07-17 12:11:48 +0400 |
commit | c78629effba2b232c5afada4b2e839a1580c0ea8 (patch) | |
tree | 34ee74d8b2d1d25c28e7b9895fdc0a9bbd5d04ad | |
parent | 6b3e98d505297e6cbd0cbd22d4f46eacb091d924 (diff) | |
download | mariadb-git-c78629effba2b232c5afada4b2e839a1580c0ea8.tar.gz |
Arjens LOG functions changes with small changes and tests added to mysql-test
Docs/manual.texi:
Manual changes to doccument new functions and function changes
mysql-test/r/func_math.result:
Extend tests for LOG family functions
mysql-test/t/func_math.test:
Extend tests for LOG family functions
sql/gen_lex_hash.cc:
Lex hash changes
sql/item_create.cc:
Rename old log function to ln
sql/item_create.h:
More log functions
sql/item_func.cc:
Implementation of new log function behavior
sql/item_func.h:
Class definition for new functions
sql/lex.h:
Function names
sql/sql_yacc.yy:
Symbols for new LOG function
tests/function.res:
One more test result change
tests/function.tst:
One more test change
BitKeeper/etc/logging_ok:
Logging to logging@openlogging.org accepted
-rw-r--r-- | BitKeeper/etc/logging_ok | 1 | ||||
-rw-r--r-- | Docs/manual.texi | 65 | ||||
-rw-r--r-- | mysql-test/r/func_math.result | 15 | ||||
-rw-r--r-- | mysql-test/t/func_math.test | 5 | ||||
-rw-r--r-- | sql/gen_lex_hash.cc | 8 | ||||
-rw-r--r-- | sql/item_create.cc | 9 | ||||
-rw-r--r-- | sql/item_create.h | 3 | ||||
-rw-r--r-- | sql/item_func.cc | 31 | ||||
-rw-r--r-- | sql/item_func.h | 20 | ||||
-rw-r--r-- | sql/lex.h | 4 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 5 | ||||
-rw-r--r-- | tests/function.res | 6 | ||||
-rw-r--r-- | tests/function.tst | 2 |
13 files changed, 152 insertions, 22 deletions
diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 6efacbf4998..cd35e6c9643 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -70,3 +70,4 @@ zak@linux.local salle@geopard.(none) walrus@mysql.com zgreant@mysql.com +peter@mysql.com diff --git a/Docs/manual.texi b/Docs/manual.texi index 83999b6daae..93272140507 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -31874,17 +31874,57 @@ mysql> SELECT EXP(2); mysql> SELECT EXP(-2); -> 0.135335 @end example -@findex LOG() -@item LOG(X) + +@findex LN() +@item LN(X) Returns the natural logarithm of @code{X}: @example +mysql> SELECT LN(2); + -> 0.693147 +mysql> SELECT LN(-2); + -> NULL +@end example + +This function was added in MySQL version 4.0.3. +It is synonymous with @code{LOG(X)} in MySQL. + +@findex LOG() +@item LOG([B,]X) +When called with one parameter, this function returns the natural logarithm +of @code{X}: +@example mysql> SELECT LOG(2); -> 0.693147 mysql> SELECT LOG(-2); -> NULL @end example -If you want the log of a number @code{X} to some arbitary base @code{B}, use -the formula @code{LOG(X)/LOG(B)}. + +When called with two parameters, this function returns the logarithm of +@code{X} for an arbitary base @code{B}: +@example +mysql> SELECT LOG(2,65536); + -> 16.000000 +mysql> SELECT LOG(1,100); + -> NULL +@end example + +The arbitrary base option was added in MySQL version 4.0.3. +@code{LOG(B,X)} is equivalent to @code{LOG(X)/LOG(B)}. + +@findex LOG2() +@item LOG2(X) +Returns the base-2 logarithm of @code{X}: +@example +mysql> SELECT LOG2(65536); + -> 16.000000 +mysql> SELECT LOG2(-100); + -> NULL +@end example + +@code{LOG2()} is useful for finding out how many bits a number would +require for storage. +This function was added in MySQL version 4.0.3. +In earlier versions, you can use @code{LOG(X)/LOG(2)} instead. @findex LOG10() @item LOG10(X) @@ -49674,12 +49714,27 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}. @cindex changes, version 4.0 @menu +* News-4.0.3:: Changes in release 4.0.3 * News-4.0.2:: Changes in release 4.0.2 (01 July 2002) * News-4.0.1:: Changes in release 4.0.1 (23 Dec 2001) * News-4.0.0:: Changes in release 4.0.0 (Oct 2001: Alpha) @end menu -@node News-4.0.2, News-4.0.1, News-4.0.x, News-4.0.x +@node News-4.0.3, News-4.0.2, News-4.0.x, News-4.0.x +@appendixsubsec Changes in release 4.0.3 + +@itemize @bullet +@item +Extended @code{LOG()} function to accept an optional arbitrary base parameter. +@xref{Mathematical functions}. +@item +Added @code{LOG2()} function (useful for finding out how many bits a number would require for storage). +@item +Added @code{LN()} natural logarithm function for compatibility with other databases. It is synonymous with @code{LOG(X)}. +@end itemize + + +@node News-4.0.2, News-4.0.1, News-4.0.3, News-4.0.x @appendixsubsec Changes in release 4.0.2 (01 July 2002) @itemize @bullet 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 5560d3cdb0d..0860e15d2e4 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -338,15 +338,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 81d597c6a5c..5a5e539a25b 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -461,9 +461,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 6a4f13940a7..af094997341 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -231,6 +231,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 @@ -1779,6 +1780,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) ; # |