-
Notifications
You must be signed in to change notification settings - Fork 109
Conversation
Signed-off-by: Theo Despoudis <thdespou@hotmail.com>
Signed-off-by: Theo Despoudis <thdespou@hotmail.com>
ctx *sql.Context, | ||
row sql.Row, | ||
) (interface{}, error) { | ||
left, err := l.Left.Eval(ctx, row) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This common block which repeats multiple times (eval + convert) we can extract to some private function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure will push a fix today
I've consolidated Log2, Ln and Log10. @kuba-- Please take a look |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also sign a request, thanks.
sql/expression/function/logarithm.go
Outdated
|
||
// IsNullable implements the sql.Expression interface. | ||
func (l *LogBase) IsNullable() bool { | ||
return l.Child.IsNullable() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO Logarithm can be NULL in ranges where function y=log b(x) doesn't exist:
- b or x is NULL
- base is <= 0 or base == 1
- x <= 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK I will add the check here also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW how can I resolve the Child value here so I can check that x <= 0
?
Also as base is float there is no nil value unless I change it to a pointer.
So far I've done something like:
func (l *LogBase) IsNullable() bool {
return l.base == float64(1) || l.base <= float64(0) || l.Child.IsNullable()
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it may work.
sql/expression/function/logarithm.go
Outdated
right = args[1] | ||
} | ||
|
||
return &Log{expression.BinaryExpression{Left: args[0], Right: right}}, nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't better to always set b
and x
instead of checking somewhere else which one is nil?
- if len == 1 => left = E, right = args[0]
- if len == 2 => left = args[0], right = args[1]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK will refactor but I took this logic from
https://github.com/src-d/go-mysql-server/blob/master/sql/expression/function/ceil_round_floor.go#L155-L166
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe, internally it's better to have everything explicit.
sql/expression/function/logarithm.go
Outdated
|
||
// Children implements the Expression interface. | ||
func (l *Log) Children() []sql.Expression { | ||
if l.Right == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO internally we should explicitly say - left is a base, right is argument.
If base is not specified in constructor then we set it up to E
, but internally we shouldn't have hidden logic, which argument stands for what.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we setup base to Math.E wouldn't that make difficult to detect if the request was using 1 argument instead of 2? For example when l.Right == nil we know that the request was log(%s)
but now every time it would be log(%s, %s)
which looks wierd.
mysql> select log(2);
+---------------------------+
| log(2.718281828459045, 2) |
+---------------------------+
| 0.6931471805599453 |
+---------------------------+
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But the header comes from the String
- right?
If yes, maybe we can add extra nice formatting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok we can just always show the base even if its not specified. and maybe use "e"
sql/expression/function/logarithm.go
Outdated
} | ||
|
||
// IsNullable implements the Expression interface. | ||
func (l *Log) IsNullable() bool { return l.Left.IsNullable() } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see comments above
sql/expression/function/logarithm.go
Outdated
|
||
// Resolved implements the Expression interface. | ||
func (l *Log) Resolved() bool { | ||
return l.Left.Resolved() && (l.Right == nil || l.Right.Resolved()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's only resolvable for arguments from domain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, but I copied that from:
Does it mean that I don't have to provide a Resolved method?
sql/expression/function/logarithm.go
Outdated
|
||
// LogBaseMaker returns LogBase creator functions with a specific base. | ||
func LogBaseMaker(base float64) func(e sql.Expression) sql.Expression { | ||
b := base |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't you pass directly the argument base
to the function NewLogBase
in the closure?
sql/expression/function/registry.go
Outdated
@@ -3,6 +3,7 @@ package function | |||
import ( | |||
"gopkg.in/src-d/go-mysql-server.v0/sql" | |||
"gopkg.in/src-d/go-mysql-server.v0/sql/expression/function/aggregation" | |||
"math" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same about import style
Signed-off-by: Theo Despoudis <thdespou@hotmail.com>
f5c4351
to
143c081
Compare
Signed-off-by: Theo Despoudis <thdespou@hotmail.com>
I've simplified the logic even more @kuba-- Please take a look |
PR adds relevant Logarithm functions:
Some examples: