Skip to content

Commit

Permalink
Added proper handling of int and float for math op (#4257)
Browse files Browse the repository at this point in the history
  • Loading branch information
harshil-goel authored Nov 19, 2019
1 parent e8cfd0d commit dc02af5
Show file tree
Hide file tree
Showing 8 changed files with 628 additions and 165 deletions.
64 changes: 46 additions & 18 deletions gql/math.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,21 +77,34 @@ func isTernary(f string) bool {
}

func isZero(f string, rval types.Val) bool {
if rval.Tid != types.FloatID {
if rval.Tid == types.FloatID {
g, ok := rval.Value.(float64)
if !ok {
return false
}
switch f {
case "floor":
return g >= 0 && g < 1.0
case "/", "%", "ceil", "sqrt", "u-":
return g == 0
case "ln":
return g == 1
}
return false
}
g, ok := rval.Value.(float64)
if !ok {
} else if rval.Tid == types.IntID {
g, ok := rval.Value.(int64)
if !ok {
return false
}
switch f {
case "floor", "/", "%", "ceil", "sqrt", "u-":
return g == 0
case "ln":
return g == 1
}
return false
}
switch f {
case "floor":
return g >= 0 && g < 1.0
case "/", "%", "ceil", "sqrt", "u-":
return g == 0
case "ln":
return g == 1
}

return false
}

Expand Down Expand Up @@ -233,15 +246,23 @@ func parseMathFunc(it *lex.ItemIterator, again bool) (*MathTree, bool, error) {
}
continue
}
// Try to parse it as a constant.
// We will try to parse the constant as an Int first, if that fails we move to float
child := &MathTree{}
v, err := strconv.ParseFloat(item.Val, 64)
i, err := strconv.ParseInt(item.Val, 10, 64)
if err != nil {
child.Var = item.Val
v, err := strconv.ParseFloat(item.Val, 64)
if err != nil {
child.Var = item.Val
} else {
child.Const = types.Val{
Tid: types.FloatID,
Value: v,
}
}
} else {
child.Const = types.Val{
Tid: types.FloatID,
Value: v,
Tid: types.IntID,
Value: i,
}
}
valueStack.push(child)
Expand Down Expand Up @@ -339,7 +360,14 @@ func (t *MathTree) stringHelper(buf *bytes.Buffer) {
}
if t.Const.Value != nil {
// Leaf node.
x.Check2(buf.WriteString(strconv.FormatFloat(t.Const.Value.(float64), 'E', -1, 64)))
var leafStr int
var err error
if t.Const.Tid == types.FloatID {
leafStr, err = buf.WriteString(strconv.FormatFloat(t.Const.Value.(float64), 'E', -1, 64))
} else if t.Const.Tid == types.IntID {
leafStr, err = buf.WriteString(strconv.FormatInt(t.Const.Value.(int64), 10))
}
x.Check2(leafStr, err)
return
}
// Non-leaf node.
Expand Down
16 changes: 8 additions & 8 deletions gql/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -494,8 +494,8 @@ func TestParseQueryWithVarValAggNested2(t *testing.T) {
a as age
b as count(friends)
c as count(relatives)
d as math(exp(a + b + 1) - ln(c))
q as math(c*-1+-b+(-b*c))
d as math(exp(a + b + 1.0) - ln(c))
q as math(c*-1.0+-b+(-b*c))
}
}
}
Expand All @@ -520,7 +520,7 @@ func TestParseQueryWithVarValAggNested4(t *testing.T) {
a as age
b as count(friends)
c as count(relatives)
d as math(exp(a + b + 1) - max(c,ln(c)) + sqrt(a%b))
d as math(exp(a + b + 1.0) - max(c,ln(c)) + sqrt(a%b))
}
}
}
Expand Down Expand Up @@ -569,16 +569,16 @@ func TestParseQueryWithVarValAggNestedConditional(t *testing.T) {
a as age
b as count(friends)
c as count(relatives)
d as math(cond(a <= 10, exp(a + b + 1), ln(c)) + 10*a)
e as math(cond(a!=10, exp(a + b + 1), ln(d)))
f as math(cond(a==10, exp(a + b + 1), ln(e)))
d as math(cond(a <= 10.0, exp(a + b + 1.0), ln(c)) + 10*a)
e as math(cond(a!=10.0, exp(a + b + 1.0), ln(d)))
f as math(cond(a==10.0, exp(a + b + 1.0), ln(e)))
}
}
}
`
res, err := Parse(Request{Str: query})
require.NoError(t, err)
require.EqualValues(t, "(+ (cond (<= a 1E+01) (exp (+ (+ a b) 1E+00)) (ln c)) (* 1E+01 a))",
require.EqualValues(t, "(+ (cond (<= a 1E+01) (exp (+ (+ a b) 1E+00)) (ln c)) (* 10 a))",
res.Query[1].Children[0].Children[3].MathExp.debugString())
require.EqualValues(t, "(cond (!= a 1E+01) (exp (+ (+ a b) 1E+00)) (ln d))",
res.Query[1].Children[0].Children[4].MathExp.debugString())
Expand All @@ -598,7 +598,7 @@ func TestParseQueryWithVarValAggNested3(t *testing.T) {
a as age
b as count(friends)
c as count(relatives)
d as math(a + b * c / a + exp(a + b + 1) - ln(c))
d as math(a + b * c / a + exp(a + b + 1.0) - ln(c))
}
}
}
Expand Down
Loading

0 comments on commit dc02af5

Please sign in to comment.