summaryrefslogtreecommitdiff
path: root/internal/mapr
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2021-10-09 21:10:29 +0300
committerPaul Buetow <paul@buetow.org>2021-10-10 13:36:41 +0300
commit97747ea0f3178f7f5890512d483fdccaa82846b0 (patch)
tree9ff1335ca26afc90e55fd6de416457e252d75a35 /internal/mapr
parent7a7169791a64190e1002e38bc9c04ad0d5c1ce1f (diff)
vetting and linting and some code restyling
Diffstat (limited to 'internal/mapr')
-rw-r--r--internal/mapr/aggregateset.go4
-rw-r--r--internal/mapr/client/aggregate.go9
-rw-r--r--internal/mapr/funcs/function.go7
-rw-r--r--internal/mapr/funcs/function_test.go21
-rw-r--r--internal/mapr/funcs/maskdigits.go2
-rw-r--r--internal/mapr/globalgroupset.go8
-rw-r--r--internal/mapr/groupset.go9
-rw-r--r--internal/mapr/logformat/default.go5
-rw-r--r--internal/mapr/logformat/default_test.go24
-rw-r--r--internal/mapr/logformat/generickv.go2
-rw-r--r--internal/mapr/logformat/parser.go12
-rw-r--r--internal/mapr/query.go17
-rw-r--r--internal/mapr/query_test.go125
-rw-r--r--internal/mapr/selectcondition.go12
-rw-r--r--internal/mapr/server/aggregate.go30
-rw-r--r--internal/mapr/setclause.go2
-rw-r--r--internal/mapr/setcondition.go15
-rw-r--r--internal/mapr/token.go11
-rw-r--r--internal/mapr/whereclause.go10
-rw-r--r--internal/mapr/wherecondition.go24
20 files changed, 180 insertions, 169 deletions
diff --git a/internal/mapr/aggregateset.go b/internal/mapr/aggregateset.go
index 14e6943..c50c7a1 100644
--- a/internal/mapr/aggregateset.go
+++ b/internal/mapr/aggregateset.go
@@ -38,7 +38,6 @@ func (s *AggregateSet) String() string {
func (s *AggregateSet) Merge(query *Query, set *AggregateSet) error {
s.Samples += set.Samples
//dlog.Common.Trace("Merge", set)
-
for _, sc := range query.Select {
storage := sc.FieldStorage
switch sc.Operation {
@@ -115,7 +114,6 @@ func (s *AggregateSet) addFloatMin(key string, value float64) {
s.FValues[key] = value
return
}
-
if f > value {
s.FValues[key] = value
}
@@ -128,7 +126,6 @@ func (s *AggregateSet) addFloatMax(key string, value float64) {
s.FValues[key] = value
return
}
-
if f < value {
s.FValues[key] = value
}
@@ -147,7 +144,6 @@ func (s *AggregateSet) setFloat(key string, value float64) {
// Aggregate data to the aggregate set.
func (s *AggregateSet) Aggregate(key string, agg AggregateOperation, value string, clientAggregation bool) (err error) {
var f float64
-
// First check if we can aggregate anything without converting value to float.
switch agg {
case Count:
diff --git a/internal/mapr/client/aggregate.go b/internal/mapr/client/aggregate.go
index d0c1d70..02a6a5a 100644
--- a/internal/mapr/client/aggregate.go
+++ b/internal/mapr/client/aggregate.go
@@ -23,7 +23,9 @@ type Aggregate struct {
}
// NewAggregate create new client aggregator.
-func NewAggregate(server string, query *mapr.Query, globalGroup *mapr.GlobalGroupSet) *Aggregate {
+func NewAggregate(server string, query *mapr.Query,
+ globalGroup *mapr.GlobalGroupSet) *Aggregate {
+
return &Aggregate{
query: query,
group: mapr.NewGroupSet(),
@@ -47,8 +49,8 @@ func (a *Aggregate) Aggregate(message string) error {
fields := a.makeFields(parts[2:])
set := a.group.GetSet(groupKey)
-
var addedSamples bool
+
for _, sc := range a.query.Select {
if val, ok := fields[sc.FieldStorage]; ok {
if err := set.Aggregate(sc.FieldStorage, sc.Operation, val, true); err != nil {
@@ -71,14 +73,12 @@ func (a *Aggregate) Aggregate(message string) error {
// Re-init local group (make it empty again).
a.group.InitSet()
}
-
return nil
}
// Create a map of key-value pairs from a part list such as ["foo=bar", "bar=baz"].
func (a *Aggregate) makeFields(parts []string) map[string]string {
fields := make(map[string]string, len(parts))
-
for _, part := range parts {
kv := strings.SplitN(part, protocol.AggregateKVDelimiter, 2)
if len(kv) != 2 {
@@ -86,6 +86,5 @@ func (a *Aggregate) makeFields(parts []string) map[string]string {
}
fields[kv[0]] = kv[1]
}
-
return fields
}
diff --git a/internal/mapr/funcs/function.go b/internal/mapr/funcs/function.go
index 0433b9a..418d86f 100644
--- a/internal/mapr/funcs/function.go
+++ b/internal/mapr/funcs/function.go
@@ -19,13 +19,12 @@ type Function struct {
// FunctionStack is a list of functions stacked each other
type FunctionStack []Function
-// NewFunctionStack parses the input string, e.g. foo(bar("arg")) and returns a corresponding function stack.
+// NewFunctionStack parses the input string, e.g. foo(bar("arg")) and returns
+// a corresponding function stack.
func NewFunctionStack(in string) (FunctionStack, string, error) {
var fs FunctionStack
-
getCallback := func(name string) (CallbackFunc, error) {
var cb CallbackFunc
-
switch name {
case "md5sum":
return Md5Sum, nil
@@ -51,7 +50,6 @@ func NewFunctionStack(in string) (FunctionStack, string, error) {
fs = append(fs, Function{name, call})
aux = aux[index+1 : len(aux)-1]
}
-
return fs, aux, nil
}
@@ -62,6 +60,5 @@ func (fs FunctionStack) Call(str string) string {
str = fs[i].call(str)
//dlog.Common.Debug("Call.result", fs[i].Name, str)
}
-
return str
}
diff --git a/internal/mapr/funcs/function_test.go b/internal/mapr/funcs/function_test.go
index 415683c..8b5d8b7 100644
--- a/internal/mapr/funcs/function_test.go
+++ b/internal/mapr/funcs/function_test.go
@@ -6,16 +6,19 @@ func TestFunction(t *testing.T) {
input := "md5sum($line)"
fs, arg, err := NewFunctionStack(input)
if err != nil {
- t.Errorf("error parsing function input '%s': %s (%v)\n", input, err.Error(), fs)
+ t.Errorf("error parsing function input '%s': %s (%v)\n",
+ input, err.Error(), fs)
}
if arg != "$line" {
- t.Errorf("error parsing function input '%s': expected argument '$line' but got '%s' (%v)\n", input, arg, fs)
+ t.Errorf("error parsing function input '%s': expected argument '$line' but "+
+ "got '%s' (%v)\n", input, arg, fs)
}
t.Log(input, fs, arg)
result := fs.Call(input)
if result != "b38699013d79e50d9d122433753959c1" {
- t.Errorf("error executing function stack '%s': expected result 'b38699013d79e50d9d122433753959c1' but got '%s' (%v)\n", input, result, fs)
+ t.Errorf("error executing function stack '%s': expected result "+
+ "'b38699013d79e50d9d122433753959c1' but got '%s' (%v)\n", input, result, fs)
}
input = "maskdigits(md5sum(maskdigits($line)))"
@@ -24,22 +27,26 @@ func TestFunction(t *testing.T) {
t.Errorf("error parsing function input '%s': %s (%v)\n", input, err.Error(), fs)
}
if arg != "$line" {
- t.Errorf("error parsing function input '%s': expected argument '$line' but got '%s' (%v)\n", input, arg, fs)
+ t.Errorf("error parsing function input '%s': expected argument '$line' but "+
+ "got '%s' (%v)\n", input, arg, fs)
}
t.Log(input, fs, arg)
result = fs.Call(input)
if result != ".fac.bbe..bb.........d...a.c..b." {
- t.Errorf("error executing function stack '%s': expected result '.fac.bbe..bb.........d...a.c..b.' but got '%s' (%v)\n", input, result, fs)
+ t.Errorf("error executing function stack '%s': expected result "+
+ "'.fac.bbe..bb.........d...a.c..b.' but got '%s' (%v)\n", input, result, fs)
}
input = "md5sum$line)"
if fs, _, err := NewFunctionStack(input); err == nil {
- t.Errorf("Expected error parsing function input '%s' (%v) but got no error\n", input, fs)
+ t.Errorf("Expected error parsing function input '%s' (%v) but got no error\n",
+ input, fs)
}
input = "md5sum(makedigits$line))"
if fs, _, err := NewFunctionStack(input); err == nil {
- t.Errorf("Expected error parsing function input '%s' (%v) but got no error\n", input, fs)
+ t.Errorf("Expected error parsing function input '%s' (%v) but got no error\n",
+ input, fs)
}
}
diff --git a/internal/mapr/funcs/maskdigits.go b/internal/mapr/funcs/maskdigits.go
index d51f3d8..925ec4d 100644
--- a/internal/mapr/funcs/maskdigits.go
+++ b/internal/mapr/funcs/maskdigits.go
@@ -3,12 +3,10 @@ package funcs
// MaskDigits masks all digits (replaces them with .)
func MaskDigits(input string) string {
s := []byte(input)
-
for i, b := range s {
if '0' <= b && b <= '9' {
s[i] = '.'
}
}
-
return string(s)
}
diff --git a/internal/mapr/globalgroupset.go b/internal/mapr/globalgroupset.go
index 50bac37..2d7f10b 100644
--- a/internal/mapr/globalgroupset.go
+++ b/internal/mapr/globalgroupset.go
@@ -17,7 +17,6 @@ func NewGlobalGroupSet() *GlobalGroupSet {
semaphore: make(chan struct{}, 1),
}
g.InitSet()
-
return &g
}
@@ -30,7 +29,6 @@ func (g *GlobalGroupSet) String() string {
func (g *GlobalGroupSet) Merge(query *Query, group *GroupSet) error {
g.semaphore <- struct{}{}
defer func() { <-g.semaphore }()
-
return g.merge(query, group)
}
@@ -48,14 +46,12 @@ func (g *GlobalGroupSet) MergeNoblock(query *Query, group *GroupSet) (bool, erro
// Merge a group set into the global group set.
func (g *GlobalGroupSet) merge(query *Query, group *GroupSet) error {
-
for groupKey, set := range group.sets {
s := g.GetSet(groupKey)
if err := s.Merge(query, set); err != nil {
return err
}
}
-
return nil
}
@@ -68,7 +64,6 @@ func (g *GlobalGroupSet) IsEmpty() bool {
func (g *GlobalGroupSet) NumSets() int {
g.semaphore <- struct{}{}
defer func() { <-g.semaphore }()
-
return len(g.sets)
}
@@ -80,7 +75,6 @@ func (g *GlobalGroupSet) SwapOut() *GroupSet {
set := &GroupSet{sets: g.sets}
g.InitSet()
-
return set
}
@@ -88,7 +82,6 @@ func (g *GlobalGroupSet) SwapOut() *GroupSet {
func (g *GlobalGroupSet) WriteResult(query *Query) error {
g.semaphore <- struct{}{}
defer func() { <-g.semaphore }()
-
return g.GroupSet.WriteResult(query)
}
@@ -96,6 +89,5 @@ func (g *GlobalGroupSet) WriteResult(query *Query) error {
func (g *GlobalGroupSet) Result(query *Query, rowsLimit int) (string, int, error) {
g.semaphore <- struct{}{}
defer func() { <-g.semaphore }()
-
return g.GroupSet.Result(query, rowsLimit)
}
diff --git a/internal/mapr/groupset.go b/internal/mapr/groupset.go
index ce7630d..6ffc8b9 100644
--- a/internal/mapr/groupset.go
+++ b/internal/mapr/groupset.go
@@ -73,7 +73,6 @@ func (g *GroupSet) Result(query *Query, rowsLimit int) (string, int, error) {
if err != nil {
return "", 0, err
}
-
if query.Limit != -1 {
rowsLimit = query.Limit
}
@@ -91,12 +90,14 @@ func (g *GroupSet) Result(query *Query, rowsLimit int) (string, int, error) {
if sc.FieldStorage == query.OrderBy {
attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderSortKeyAttr)
}
+
for _, groupBy := range query.GroupBy {
if sc.FieldStorage == groupBy {
attrs = append(attrs, config.Client.TermColors.MaprTable.HeaderGroupKeyAttr)
break
}
}
+
color.PaintWithAttrs(sb, str,
config.Client.TermColors.MaprTable.HeaderFg,
config.Client.TermColors.MaprTable.HeaderBg,
@@ -191,7 +192,6 @@ func (*GroupSet) writeQueryFile(query *Query) error {
fd.WriteString(query.RawQuery)
os.Rename(tmpQueryFile, queryFile)
-
return nil
}
@@ -256,7 +256,6 @@ func (g *GroupSet) WriteResult(query *Query) error {
func (g *GroupSet) result(query *Query, gatherWidths bool) ([]result, []int, error) {
var rows []result
widths := make([]int, len(query.Select))
-
var valueStr string
var value float64
@@ -284,7 +283,8 @@ func (g *GroupSet) result(query *Query, gatherWidths bool) ([]result, []int, err
value = set.FValues[sc.FieldStorage] / float64(set.Samples)
valueStr = fmt.Sprintf("%f", value)
default:
- return rows, widths, fmt.Errorf("Unknown aggregation method '%v'", sc.Operation)
+ return rows, widths, fmt.Errorf("Unknown aggregation method '%v'",
+ sc.Operation)
}
if sc.FieldStorage == query.OrderBy {
@@ -302,7 +302,6 @@ func (g *GroupSet) result(query *Query, gatherWidths bool) ([]result, []int, err
widths[i] = len(valueStr)
}
}
-
rows = append(rows, r)
}
diff --git a/internal/mapr/logformat/default.go b/internal/mapr/logformat/default.go
index 8016667..9b6c855 100644
--- a/internal/mapr/logformat/default.go
+++ b/internal/mapr/logformat/default.go
@@ -11,9 +11,10 @@ import (
func (p *Parser) MakeFieldsDEFAULT(maprLine string) (map[string]string, error) {
splitted := strings.Split(maprLine, protocol.FieldDelimiter)
- if len(splitted) < 11 || !strings.HasPrefix(splitted[9], "MAPREDUCE:") || !strings.HasPrefix(splitted[0], "INFO") {
+ if len(splitted) < 11 || !strings.HasPrefix(splitted[9], "MAPREDUCE:") ||
+ !strings.HasPrefix(splitted[0], "INFO") {
// Not a DTail mapreduce log line.
- return nil, IgnoreFieldsErr
+ return nil, ErrIgnoreFields
}
fields := make(map[string]string, len(splitted)+8)
diff --git a/internal/mapr/logformat/default_test.go b/internal/mapr/logformat/default_test.go
index a777156..28e1acc 100644
--- a/internal/mapr/logformat/default_test.go
+++ b/internal/mapr/logformat/default_test.go
@@ -32,49 +32,57 @@ func TestDefaultLogFormat(t *testing.T) {
if val, ok := fields["$severity"]; !ok {
t.Errorf("Expected field '$severity', but no such field there in '%s'\n", input)
} else if val != "INFO" {
- t.Errorf("Expected 'Info' stored in field '$severity', but got '%s' in '%s'\n", val, input)
+ t.Errorf("Expected 'Info' stored in field '$severity', but got '%s' in '%s'\n",
+ val, input)
}
if val, ok := fields["$time"]; !ok {
t.Errorf("Expected field '$time', but no such field there in '%s'\n", input)
} else if val != time {
- t.Errorf("Expected '%s' stored in field '$time', but got '%s' in '%s'\n", time, val, input)
+ t.Errorf("Expected '%s' stored in field '$time', but got '%s' in '%s'\n",
+ time, val, input)
}
if val, ok := fields["$date"]; !ok {
t.Errorf("Expected field '$date', but no such field there in '%s'\n", input)
} else if val != date {
- t.Errorf("Expected '%s' stored in field '$date', but got '%s' in '%s'\n", date, val, input)
+ t.Errorf("Expected '%s' stored in field '$date', but got '%s' in '%s'\n",
+ date, val, input)
}
if val, ok := fields["$hour"]; !ok {
t.Errorf("Expected field '$hour', but no such field there in '%s'\n", input)
} else if val != hour {
- t.Errorf("Expected '%s' stored in field '$hour', but got '%s' in '%s'\n", hour, val, input)
+ t.Errorf("Expected '%s' stored in field '$hour', but got '%s' in '%s'\n",
+ hour, val, input)
}
if val, ok := fields["$minute"]; !ok {
t.Errorf("Expected field '$minute', but no such field there in '%s'\n", input)
} else if val != minute {
- t.Errorf("Expected '%s' stored in field '$minute', but got '%s' in '%s'\n", minute, val, input)
+ t.Errorf("Expected '%s' stored in field '$minute', but got '%s' in '%s'\n",
+ minute, val, input)
}
if val, ok := fields["$second"]; !ok {
t.Errorf("Expected field '$second', but no such field there in '%s'\n", input)
} else if val != second {
- t.Errorf("Expected '%s' stored in field '$second', but got '%s' in '%s'\n", second, val, input)
+ t.Errorf("Expected '%s' stored in field '$second', but got '%s' in '%s'\n",
+ second, val, input)
}
if val, ok := fields["foo"]; !ok {
t.Errorf("Expected field 'foo', but no such field there in '%s'\n", input)
} else if val != "bar" {
- t.Errorf("Expected 'bar' stored in field 'foo', but got '%s' in '%s'\n", val, input)
+ t.Errorf("Expected 'bar' stored in field 'foo', but got '%s' in '%s'\n",
+ val, input)
}
if val, ok := fields["bar"]; !ok {
t.Errorf("Expected field 'bar', but no such field there in '%s'\n", input)
} else if val != "foo" {
- t.Errorf("Expected 'foo' stored in field 'bar', but got '%s' in '%s'\n", val, input)
+ t.Errorf("Expected 'foo' stored in field 'bar', but got '%s' in '%s'\n",
+ val, input)
}
}
diff --git a/internal/mapr/logformat/generickv.go b/internal/mapr/logformat/generickv.go
index 3769c22..433eb5f 100644
--- a/internal/mapr/logformat/generickv.go
+++ b/internal/mapr/logformat/generickv.go
@@ -6,7 +6,7 @@ import (
"github.com/mimecast/dtail/internal/protocol"
)
-// MakeFieldsGENERICKV is the generic key-value logfile parser.
+// MakeFieldsGENERIGKV is the generic key-value logfile parser.
func (p *Parser) MakeFieldsGENERIGKV(maprLine string) (map[string]string, error) {
splitted := strings.Split(maprLine, protocol.FieldDelimiter)
fields := make(map[string]string, len(splitted))
diff --git a/internal/mapr/logformat/parser.go b/internal/mapr/logformat/parser.go
index a352580..129081d 100644
--- a/internal/mapr/logformat/parser.go
+++ b/internal/mapr/logformat/parser.go
@@ -11,7 +11,8 @@ import (
"github.com/mimecast/dtail/internal/mapr"
)
-var IgnoreFieldsErr error = errors.New("Ignore this field set")
+// ErrIgnoreFields indicates that the fields should be ignored.
+var ErrIgnoreFields error = errors.New("Ignore this field set")
// Parser is used to parse the mapreduce information from the server log files.
type Parser struct {
@@ -26,11 +27,9 @@ type Parser struct {
// NewParser returns a new log parser.
func NewParser(logFormatName string, query *mapr.Query) (*Parser, error) {
hostname, err := os.Hostname()
-
if err != nil {
return nil, err
}
-
now := time.Now()
zone, offset := now.Zone()
@@ -44,7 +43,6 @@ func NewParser(logFormatName string, query *mapr.Query) (*Parser, error) {
if err != nil {
return nil, err
}
-
return &p, nil
}
@@ -53,7 +51,6 @@ func NewParser(logFormatName string, query *mapr.Query) (*Parser, error) {
// Parser. Whereas MODULENAME must be a upeprcase string.
func (p *Parser) reflectLogFormat(logFormatName string) error {
methodName := fmt.Sprintf("MakeFields%s", strings.ToUpper(logFormatName))
-
rt := reflect.TypeOf(p)
method, ok := rt.MethodByName(methodName)
if !ok {
@@ -62,7 +59,6 @@ func (p *Parser) reflectLogFormat(logFormatName string) error {
p.makeFieldsFunc = method.Func
p.makeFieldsReceiver = reflect.ValueOf(p)
-
return nil
}
@@ -70,15 +66,11 @@ func (p *Parser) reflectLogFormat(logFormatName string) error {
func (p *Parser) MakeFields(maprLine string) (fields map[string]string, err error) {
inputValues := []reflect.Value{p.makeFieldsReceiver, reflect.ValueOf(maprLine)}
returnValues := p.makeFieldsFunc.Call(inputValues)
-
errInterface := returnValues[1].Interface()
-
if errInterface == nil {
fields, err = returnValues[0].Interface().(map[string]string), nil
return
}
-
fields, err = returnValues[0].Interface().(map[string]string), errInterface.(error)
-
return
}
diff --git a/internal/mapr/query.go b/internal/mapr/query.go
index 6c1d849..d7c32bd 100644
--- a/internal/mapr/query.go
+++ b/internal/mapr/query.go
@@ -32,7 +32,9 @@ type Query struct {
}
func (q Query) String() string {
- return fmt.Sprintf("Query(Select:%v,Table:%s,Where:%v,Set:%vGroupBy:%v,GroupKey:%s,OrderBy:%v,ReverseOrder:%v,Interval:%v,Limit:%d,Outfile:%s,RawQuery:%s,tokens:%v,LogFormat:%s)",
+ return fmt.Sprintf("Query(Select:%v,Table:%s,Where:%v,Set:%vGroupBy:%v,"+
+ "GroupKey:%s,OrderBy:%v,ReverseOrder:%v,Interval:%v,Limit:%d,Outfile:%s,"+
+ "RawQuery:%s,tokens:%v,LogFormat:%s)",
q.Select,
q.Table,
q.Where,
@@ -54,18 +56,14 @@ func NewQuery(queryStr string) (*Query, error) {
if queryStr == "" {
return nil, nil
}
-
tokens := tokenize(queryStr)
-
q := Query{
RawQuery: queryStr,
tokens: tokens,
Interval: time.Second * 5,
Limit: -1,
}
-
- err := q.parse(tokens)
- return &q, err
+ return &q, q.parse(tokens)
}
// HasOutfile returns true if query result will be written to a CVS output file.
@@ -174,13 +172,13 @@ func (q *Query) parse(tokens []token) error {
}
if len(q.Select) < 1 {
- return errors.New(invalidQuery + "Expected at least one field in 'select' clause but got none")
+ return errors.New(invalidQuery + "Expected at least one field in 'select' " +
+ "clause but got none")
}
if len(q.GroupBy) == 0 {
field := q.Select[0].Field
q.GroupBy = append(q.GroupBy, field)
}
-
if q.OrderBy != "" {
var orderFieldIsValid bool
for _, sc := range q.Select {
@@ -190,7 +188,8 @@ func (q *Query) parse(tokens []token) error {
}
}
if !orderFieldIsValid {
- return errors.New(invalidQuery + fmt.Sprintf("Can not '(r)order by' '%s', must be present in 'select' clause", q.OrderBy))
+ return errors.New(invalidQuery + fmt.Sprintf("Can not '(r)order by' '%s',"+
+ "must be present in 'select' clause", q.OrderBy))
}
}
diff --git a/internal/mapr/query_test.go b/internal/mapr/query_test.go
index b0b6c3a..88f7387 100644
--- a/internal/mapr/query_test.go
+++ b/internal/mapr/query_test.go
@@ -13,18 +13,25 @@ func TestParseQuerySimple(t *testing.T) {
"select foo from bar where baz <",
"select foo from bar where baz < 100 bay eq 12 group",
"select foo from bar where baz < 100 bay eq 12 group by foo order by",
- "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz order by foo limit",
- "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz order by foo limit set foo = bar;",
+ "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz " +
+ "order by foo limit",
+ "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz " +
+ "order by foo limit set foo = bar;",
}
okQueries := []string{"select foo from bar",
"select foo from bar where",
"select foo from bar where baz < 100 bay eq 12",
"select foo from bar where baz < 100, bay eq 12",
"select foo from bar where baz < 100 and bay eq 12",
- "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz order by foo",
- "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz order by foo limit 23",
- "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz order by foo limit 23 outfile \"result.csv\"",
- "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz order by foo limit 23 outfile \"result.csv\" set $foo = maskdigits(bar), $baz = 12, $bay = $foo;",
+ "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz " +
+ "order by foo",
+ "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz " +
+ "order by foo limit 23",
+ "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz " +
+ "order by foo limit 23 outfile \"result.csv\"",
+ "select foo from bar where baz < 100 bay eq 12 group by foo, bar, baz " +
+ "order by foo limit 23 outfile \"result.csv\" " +
+ "set $foo = maskdigits(bar), $baz = 12, $bay = $foo;",
}
for _, queryStr := range errorQueries {
@@ -46,8 +53,13 @@ func TestParseQuerySimple(t *testing.T) {
func TestParseQueryDeep(t *testing.T) {
dialects := []string{
- "select s1, `from`, count(s3) from table where w1 == 2 and w2 eq \"free beer\" group by g1, g2 order by count(s3) interval 10 limit 23 set $foo = maskdigits(bar), $baz = 12, $bay = $foo logformat generic",
- "SELECT s1, `from`, COUNT(s3) FROM table WHERE w1 == 2 AND w2 eq \"free beer\" GROUP g1, g2 ORDER count(s3) INTERVAL 10 LIMIT 23 SET $foo = maskdigits(bar), $baz = 12, $bay = $foo logformat generic",
+ "select s1, `from`, count(s3) from table where w1 == 2 and w2 eq " +
+ "\"free beer\" group by g1, g2 order by count(s3) interval 10 limit 23 " +
+ "set $foo = maskdigits(bar), $baz = 12, $bay = $foo logformat generic",
+
+ "SELECT s1, `from`, COUNT(s3) FROM table WHERE w1 == 2 AND w2 eq " +
+ "\"free beer\" GROUP g1, g2 ORDER count(s3) INTERVAL 10 LIMIT 23 " +
+ "SET $foo = maskdigits(bar), $baz = 12, $bay = $foo logformat generic",
}
for _, queryStr := range dialects {
@@ -55,119 +67,144 @@ func TestParseQueryDeep(t *testing.T) {
if err != nil {
t.Errorf("%s: %s", err.Error(), queryStr)
}
-
t.Log(q)
// 'select' clause
if len(q.Select) != 3 {
- t.Errorf("Expected three elements in 'select' clause but got '%v': %s\n%v", q.Select, queryStr, q)
+ t.Errorf("Expected three elements in 'select' clause but got '%v': %s\n%v",
+ q.Select, queryStr, q)
}
-
if q.Select[0].Field != "s1" {
- t.Errorf("Expected 's1' as first element in 'select' clause but got '%v': %s\n%v", q.Select[0].Field, queryStr, q)
+ t.Errorf("Expected 's1' as first element in 'select' clause but got '%v': %s\n%v",
+ q.Select[0].Field, queryStr, q)
}
if q.Select[0].Operation != Last {
- t.Errorf("Expected 'last' as aggregation function of first element in 'select' clause but got '%v': %s\n%v", q.Select[0].Operation, queryStr, q)
+ t.Errorf("Expected 'last' as aggregation function of first element in "+
+ "'select' clause but got '%v': %s\n%v", q.Select[0].Operation, queryStr, q)
}
-
if q.Select[1].Field != "from" {
- t.Errorf("Expected 'from' as second element in 'select' clause but got '%v': %s\n%v", q.Select[1].Field, queryStr, q)
+ t.Errorf("Expected 'from' as second element in 'select' clause but got "+
+ "'%v': %s\n%v", q.Select[1].Field, queryStr, q)
}
if q.Select[1].Operation != Last {
- t.Errorf("Expected 'last' as aggregation function of second element in 'select' clause but got '%v': %s\n%v", q.Select[1].Operation, queryStr, q)
+ t.Errorf("Expected 'last' as aggregation function of second element in "+
+ "'select' clause but got '%v': %s\n%v", q.Select[1].Operation, queryStr, q)
}
-
if q.Select[2].Field != "s3" {
- t.Errorf("Expected 's3' as third element in 'select' clause but got '%v': %s\n%v", q.Select[2].Field, queryStr, q)
+ t.Errorf("Expected 's3' as third element in 'select' clause but got "+
+ "'%v': %s\n%v", q.Select[2].Field, queryStr, q)
}
if q.Select[2].Operation != Count {
- t.Errorf("Expected 'count' as aggregation function of third element in 'select' clause but got '%v': %s\n%v", q.Select[2].Operation, queryStr, q)
+ t.Errorf("Expected 'count' as aggregation function of third element in "+
+ "'select' clause but got '%v': %s\n%v", q.Select[2].Operation, queryStr, q)
}
if q.Select[2].FieldStorage != "count(s3)" {
- t.Errorf("Expected 'count(s3)' as third element's storage in 'select' clause but got '%v': %s\n%v", q.Select[2].FieldStorage, queryStr, q)
+ t.Errorf("Expected 'count(s3)' as third element's storage in 'select' "+
+ "clause but got '%v': %s\n%v", q.Select[2].FieldStorage, queryStr, q)
}
// 'from' clause
if q.Table != "TABLE" {
- t.Errorf("Expected 'TABLE' in 'from' clause but got '%v': %s\n%v", q.Table, queryStr, q)
+ t.Errorf("Expected 'TABLE' in 'from' clause but got '%v': %s\n%v",
+ q.Table, queryStr, q)
}
// 'where' clause
if len(q.Where) != 2 {
- t.Errorf("Expected two elements in 'where' clause but got '%v': %s\n%v", q.Where, queryStr, q)
+ t.Errorf("Expected two elements in 'where' clause but got '%v': %s\n%v",
+ q.Where, queryStr, q)
}
if q.Where[0].lString != "w1" {
- t.Errorf("Expected w1 as first element in 'where' clause but got '%v': %s\n%v", q.Where[0].lString, queryStr, q)
+ t.Errorf("Expected w1 as first element in 'where' clause but got '%v': %s\n%v",
+ q.Where[0].lString, queryStr, q)
}
if q.Where[0].Operation != FloatEq {
- t.Errorf("Expected FloatEq operation in first 'where' condition but got '%v': %s\n%v", q.Where[0].Operation, queryStr, q)
+ t.Errorf("Expected FloatEq operation in first 'where' condition but got "+
+ "'%v': %s\n%v", q.Where[0].Operation, queryStr, q)
}
if q.Where[0].rFloat != 2 {
- t.Errorf("Expected '2' as float argument in first 'where' condition but got '%v': %s\n%v", q.Where[0].rFloat, queryStr, q)
+ t.Errorf("Expected '2' as float argument in first 'where' condition but "+
+ "got '%v': %s\n%v", q.Where[0].rFloat, queryStr, q)
}
if q.Where[1].lString != "w2" {
- t.Errorf("Expected w2 as second element in 'where' clause but got '%v': %s\n%v", q.Where[1].lString, queryStr, q)
+ t.Errorf("Expected w2 as second element in 'where' clause but got '%v': "+
+ "%s\n%v", q.Where[1].lString, queryStr, q)
}
if q.Where[1].Operation != StringEq {
- t.Errorf("Expected StringEq operation in second 'where' condition but got '%v': %s\n%v", q.Where[0].Operation, queryStr, q)
+ t.Errorf("Expected StringEq operation in second 'where' condition but got "+
+ "'%v': %s\n%v", q.Where[0].Operation, queryStr, q)
}
if q.Where[1].rString != "free beer" {
- t.Errorf("Expected 'free beer' as string argument in second 'where' condition but got '%v': %s\n%v", q.Where[0].rString, queryStr, q)
+ t.Errorf("Expected 'free beer' as string argument in second 'where' "+
+ "condition but got '%v': %s\n%v", q.Where[0].rString, queryStr, q)
}
// 'group by' clause
if len(q.GroupBy) != 2 {
- t.Errorf("Expected two elements in 'group by' clause but got '%v': %s\n%v", q.GroupBy, queryStr, q)
+ t.Errorf("Expected two elements in 'group by' clause but got '%v': %s\n%v",
+ q.GroupBy, queryStr, q)
}
if q.GroupBy[0] != "g1" {
- t.Errorf("Expected 'g1' as first element in 'group by' clause but got '%v': %s\n%v", q.GroupBy[0], queryStr, q)
+ t.Errorf("Expected 'g1' as first element in 'group by' clause but got "+
+ "'%v': %s\n%v", q.GroupBy[0], queryStr, q)
}
if q.GroupBy[1] != "g2" {
- t.Errorf("Expected 'g2' as second element in 'group by' clause but got '%v': %s\n%v", q.GroupBy[1], queryStr, q)
+ t.Errorf("Expected 'g2' as second element in 'group by' clause but got "+
+ "'%v': %s\n%v", q.GroupBy[1], queryStr, q)
}
if q.GroupKey != "g1,g2" {
- t.Errorf("Expected 'g1,g2' as group key in 'group by' clause but got '%v': %s\n%v", q.GroupKey, queryStr, q)
+ t.Errorf("Expected 'g1,g2' as group key in 'group by' clause but got "+
+ "'%v': %s\n%v", q.GroupKey, queryStr, q)
}
// 'order by' clause
if q.OrderBy != "count(s3)" {
- t.Errorf("Expected 'count(s3)' as element in 'order by' clause but got '%v': %s\n%v", q.OrderBy, queryStr, q)
+ t.Errorf("Expected 'count(s3)' as element in 'order by' clause but got "+
+ "'%v': %s\n%v", q.OrderBy, queryStr, q)
}
// 'interval' clause
if q.Interval != time.Second*time.Duration(10) {
- t.Errorf("Expected '10s' as duration 'interval' clause but got '%v': %s\n%v", q.Interval, queryStr, q)
+ t.Errorf("Expected '10s' as duration 'interval' clause but got '%v': %s\n%v",
+ q.Interval, queryStr, q)
}
// 'limit' clause
if q.Limit != 23 {
- t.Errorf("Expected '23' as limit in 'limit' clause but got '%v': %s\n%v", q.Limit, queryStr, q)
+ t.Errorf("Expected '23' as limit in 'limit' clause but got '%v': %s\n%v",
+ q.Limit, queryStr, q)
}
// 'set' clause
if q.Set[0].lString != "$foo" {
- t.Errorf("Expected '$foo' lvalue in first 'set' condition clause but got '%v': %s\n%v", q.Set[0].lString, queryStr, q)
+ t.Errorf("Expected '$foo' lvalue in first 'set' condition clause but got "+
+ "'%v': %s\n%v", q.Set[0].lString, queryStr, q)
}
if q.Set[0].rString != "bar" {
- t.Errorf("Expected 'bar' rvalue in first 'set' condition clause but got '%v': %s\n%v", q.Set[0].rString, queryStr, q)
+ t.Errorf("Expected 'bar' rvalue in first 'set' condition clause but got "+
+ "'%v': %s\n%v", q.Set[0].rString, queryStr, q)
}
-
if q.Set[1].lString != "$baz" {
- t.Errorf("Expected '$baz' lvalue in second 'set' condition clause but got '%v': %s\n%v", q.Set[1].lString, queryStr, q)
+ t.Errorf("Expected '$baz' lvalue in second 'set' condition clause but got "+
+ "'%v': %s\n%v", q.Set[1].lString, queryStr, q)
}
if q.Set[1].rString != "12" {
- t.Errorf("Expected '12' rvalue in second 'set' condition clause but got '%v': %s\n%v", q.Set[1].rString, queryStr, q)
+ t.Errorf("Expected '12' rvalue in second 'set' condition clause but got "+
+ "'%v': %s\n%v", q.Set[1].rString, queryStr, q)
}
-
if q.Set[2].lString != "$bay" {
- t.Errorf("Expected '$bay' lvalue in third 'set' condition clause but got '%v': %s\n%v", q.Set[2].lString, queryStr, q)
+ t.Errorf("Expected '$bay' lvalue in third 'set' condition clause but got "+
+ "'%v': %s\n%v", q.Set[2].lString, queryStr, q)
}
if q.Set[2].rString != "$foo" {
- t.Errorf("Expected '$foo' rvalue in third 'set' condition clause but got '%v': %s\n%v", q.Set[2].rString, queryStr, q)
+ t.Errorf("Expected '$foo' rvalue in third 'set' condition clause but got "+
+ "'%v': %s\n%v", q.Set[2].rString, queryStr, q)
}
+ // 'logformat' clause
if q.LogFormat != "generic" {
- t.Errorf("Expected 'generic' logformat got '%v': %s\n%v", q.LogFormat, queryStr, q)
+ t.Errorf("Expected 'generic' logformat got '%v': %s\n%v",
+ q.LogFormat, queryStr, q)
}
}
}
diff --git a/internal/mapr/selectcondition.go b/internal/mapr/selectcondition.go
index d6aa0d4..5cfb8c7 100644
--- a/internal/mapr/selectcondition.go
+++ b/internal/mapr/selectcondition.go
@@ -37,7 +37,6 @@ func (sc selectCondition) String() string {
func makeSelectConditions(tokens []token) ([]selectCondition, error) {
var sel []selectCondition
-
// Parse select aggregation, e.g. sum(foo)
parse := func(token token) (selectCondition, error) {
var sc selectCondition
@@ -52,13 +51,15 @@ func makeSelectConditions(tokens []token) ([]selectCondition, error) {
a := strings.Split(tokenStr, "(")
if len(a) != 2 {
- return sc, errors.New(invalidQuery + "Can't parse 'select' aggregation: " + token.str)
+ return sc, errors.New(invalidQuery + "Can't parse 'select' aggregation: " +
+ token.str)
}
agg := a[0] // Aggregation, e.g. 'sum'
b := strings.Split(a[1], ")")
if len(b) != 2 {
- return sc, errors.New(invalidQuery + "Can't parse 'select' field name from aggregation: " + token.str)
+ return sc, errors.New(invalidQuery + "Can't parse 'select' field name " +
+ "from aggregation: " + token.str)
}
sc.Field = b[0] // Field name, e.g. 'foo'
sc.FieldStorage = tokenStr // e.g. 'sum(foo)'
@@ -79,9 +80,9 @@ func makeSelectConditions(tokens []token) ([]selectCondition, error) {
case "len":
sc.Operation = Len
default:
- return sc, errors.New(invalidQuery + "Unknown aggregation in 'select' clause: " + agg)
+ return sc, errors.New(invalidQuery +
+ "Unknown aggregation in 'select' clause: " + agg)
}
-
return sc, nil
}
@@ -92,6 +93,5 @@ func makeSelectConditions(tokens []token) ([]selectCondition, error) {
}
sel = append(sel, sc)
}
-
return sel, nil
}
diff --git a/internal/mapr/server/aggregate.go b/internal/mapr/server/aggregate.go
index 1f5d1c3..97fee11 100644
--- a/internal/mapr/server/aggregate.go
+++ b/internal/mapr/server/aggregate.go
@@ -63,16 +63,14 @@ func NewAggregate(queryStr string) (*Aggregate, error) {
}
}
- a := Aggregate{
+ return &Aggregate{
done: internal.NewDone(),
NextLinesCh: make(chan chan line.Line, 10),
serialize: make(chan struct{}),
hostname: s[0],
query: query,
parser: logParser,
- }
-
- return &a, nil
+ }, nil
}
// Shutdown the aggregation engine.
@@ -95,12 +93,10 @@ func (a *Aggregate) Start(ctx context.Context, maprMessages chan<- string) {
}()
fieldsCh := a.fieldsFromLines(myCtx)
-
// Add fields (e.g. via 'set' clause)
if len(a.query.Set) > 0 {
fieldsCh = a.setAdditionalFields(myCtx, fieldsCh)
}
-
// Periodically pre-aggregate data every a.query.Interval seconds.
go a.aggregateTimer(myCtx)
a.aggregateAndSerialize(myCtx, fieldsCh, maprMessages)
@@ -147,17 +143,18 @@ func (a *Aggregate) fieldsFromLines(ctx context.Context) <-chan map[string]strin
maprLine := strings.TrimSpace(line.Content.String())
fields, err := a.parser.MakeFields(maprLine)
- // Can not recycle here for some rason.
+ // Can't recycle it here yet, as field slices are still
+ // TODO: Add unit test reading from multiple mapreduce files lines.
+ // TODO: Add capability to recycle this bytes buffer.
//pool.RecycleBytesBuffer(line.Content)
if err != nil {
// Should fields be ignored anyway?
- if err != logformat.IgnoreFieldsErr {
+ if err != logformat.ErrIgnoreFields {
dlog.Common.Error(fields, err)
}
continue
}
-
if !a.query.WhereClause(fields) {
continue
}
@@ -175,12 +172,12 @@ func (a *Aggregate) fieldsFromLines(ctx context.Context) <-chan map[string]strin
return fieldsCh
}
-func (a *Aggregate) setAdditionalFields(ctx context.Context, fieldsCh <-chan map[string]string) <-chan map[string]string {
- newFieldsCh := make(chan map[string]string)
+func (a *Aggregate) setAdditionalFields(ctx context.Context,
+ fieldsCh <-chan map[string]string) <-chan map[string]string {
+ newFieldsCh := make(chan map[string]string)
go func() {
defer close(newFieldsCh)
-
for {
fields, ok := <-fieldsCh
if !ok {
@@ -196,19 +193,18 @@ func (a *Aggregate) setAdditionalFields(ctx context.Context, fieldsCh <-chan map
}
}
}()
-
return newFieldsCh
}
-func (a *Aggregate) aggregateAndSerialize(ctx context.Context, fieldsCh <-chan map[string]string, maprMessages chan<- string) {
- group := mapr.NewGroupSet()
+func (a *Aggregate) aggregateAndSerialize(ctx context.Context,
+ fieldsCh <-chan map[string]string, maprMessages chan<- string) {
+ group := mapr.NewGroupSet()
serialize := func() {
dlog.Common.Info("Serializing mapreduce result")
group.Serialize(ctx, maprMessages)
group = mapr.NewGroupSet()
}
-
for {
select {
case fields, ok := <-fieldsCh:
@@ -227,7 +223,6 @@ func (a *Aggregate) aggregateAndSerialize(ctx context.Context, fieldsCh <-chan m
func (a *Aggregate) aggregate(group *mapr.GroupSet, fields map[string]string) {
var sb strings.Builder
-
for i, field := range a.query.GroupBy {
if i > 0 {
sb.WriteString(protocol.AggregateGroupKeyCombinator)
@@ -254,7 +249,6 @@ func (a *Aggregate) aggregate(group *mapr.GroupSet, fields map[string]string) {
set.Samples++
return
}
-
dlog.Common.Trace("Aggregated data locally without adding new samples")
}
diff --git a/internal/mapr/setclause.go b/internal/mapr/setclause.go
index b4c2f73..1843d31 100644
--- a/internal/mapr/setclause.go
+++ b/internal/mapr/setclause.go
@@ -7,7 +7,6 @@ func (q *Query) SetClause(fields map[string]string) error {
if !ok {
continue
}
-
switch sc.rType {
case FunctionStack:
fields[sc.lString] = sc.functionStack.Call(value)
@@ -15,6 +14,5 @@ func (q *Query) SetClause(fields map[string]string) error {
fields[sc.lString] = value
}
}
-
return nil
}
diff --git a/internal/mapr/setcondition.go b/internal/mapr/setcondition.go
index 8c5cfc9..92b21f4 100644
--- a/internal/mapr/setcondition.go
+++ b/internal/mapr/setcondition.go
@@ -39,20 +39,22 @@ func makeSetConditions(tokens []token) (set []setCondition, err error) {
switch setOp {
case "=":
default:
- return sc, nil, errors.New(invalidQuery + "Unknown operation in 'set' clause: " + setOp)
+ return sc, nil, errors.New(invalidQuery + "Unknown operation in 'set' " +
+ "clause: " + setOp)
}
if !tokens[0].isBareword {
- return sc, nil, errors.New(invalidQuery + "Expected bareword at 'set' clause's lValue: " + tokens[0].str)
+ return sc, nil, errors.New(invalidQuery + "Expected bareword at 'set' " +
+ "clause's lValue: " + tokens[0].str)
}
-
sc.lString = tokens[0].str
if !strings.HasPrefix(sc.lString, "$") {
- return sc, nil, errors.New(invalidQuery + "Expected field variable name (starting with $) at 'set' clause's lValue: " + tokens[0].str)
+ return sc, nil, errors.New(invalidQuery + "Expected field variable name " +
+ "(starting with $) at 'set' clause's lValue: " + tokens[0].str)
}
sc.rType = Field
-
rString := tokens[2].str
+
// Seems like a function call?
if strings.HasSuffix(rString, ")") {
functionStack, functionArg, err := funcs.NewFunctionStack(tokens[2].str)
@@ -72,7 +74,6 @@ func makeSetConditions(tokens []token) (set []setCondition, err error) {
} else {
sc.rType = Field
}
-
return sc, tokens[3:], nil
}
@@ -84,10 +85,8 @@ func makeSetConditions(tokens []token) (set []setCondition, err error) {
if err != nil {
return nil, err
}
-
set = append(set, sc)
tokens = tokensConsumeOptional(tokens, ",")
}
-
return
}
diff --git a/internal/mapr/token.go b/internal/mapr/token.go
index 7c6578b..6ac7631 100644
--- a/internal/mapr/token.go
+++ b/internal/mapr/token.go
@@ -4,7 +4,8 @@ import (
"strings"
)
-var keywords = [...]string{"select", "from", "where", "set", "group", "rorder", "order", "interval", "limit", "outfile", "logformat"}
+var keywords = [...]string{"select", "from", "where", "set", "group", "rorder",
+ "order", "interval", "limit", "outfile", "logformat"}
// Represents a parsed token, used to parse the mapr query.
type token struct {
@@ -16,13 +17,11 @@ func (t token) isKeyword() bool {
if !t.isBareword {
return false
}
-
for _, keyword := range keywords {
if strings.ToLower(t.str) == keyword {
return true
}
}
-
return false
}
@@ -32,7 +31,6 @@ func (t token) String() string {
func tokenize(queryStr string) []token {
var tokens []token
-
for i, part := range strings.Split(queryStr, "\"") {
// Even i, means that it is not a quoted string
if i%2 == 0 {
@@ -53,14 +51,12 @@ func tokenize(queryStr string) []token {
}
tokens = append(tokens, token)
}
-
return tokens
}
func tokensConsume(tokens []token) ([]token, []token) {
//dlog.Common.Trace("=====================")
var consumed []token
-
for i, t := range tokens {
if t.isKeyword() {
//dlog.Common.Trace("keyword", t)
@@ -84,7 +80,6 @@ func tokensConsume(tokens []token) ([]token, []token) {
//dlog.Common.Trace("bare", token)
consumed = append(consumed, t)
}
-
//dlog.Common.Trace("result", consumed)
return nil, consumed
}
@@ -95,7 +90,6 @@ func tokensConsumeStr(tokens []token) ([]token, []string) {
for _, token := range found {
strings = append(strings, token.str)
}
-
return tokens, strings
}
@@ -106,6 +100,5 @@ func tokensConsumeOptional(tokens []token, optional string) []token {
if strings.ToLower(tokens[0].str) == strings.ToLower(optional) {
return tokens[1:]
}
-
return tokens
}
diff --git a/internal/mapr/whereclause.go b/internal/mapr/whereclause.go
index 6356d94..d9f32eb 100644
--- a/internal/mapr/whereclause.go
+++ b/internal/mapr/whereclause.go
@@ -10,7 +10,6 @@ import (
func (q *Query) WhereClause(fields map[string]string) bool {
for _, wc := range q.Where {
var ok bool
-
if wc.Operation > FloatOperation {
var lValue, rValue float64
if lValue, ok = whereClauseFloatValue(fields, wc.lString, wc.lFloat, wc.lType); !ok {
@@ -36,11 +35,12 @@ func (q *Query) WhereClause(fields map[string]string) bool {
return false
}
}
-
return true
}
-func whereClauseFloatValue(fields map[string]string, str string, float float64, t fieldType) (float64, bool) {
+func whereClauseFloatValue(fields map[string]string, str string, float float64,
+ t fieldType) (float64, bool) {
+
switch t {
case Float:
return float, true
@@ -60,7 +60,9 @@ func whereClauseFloatValue(fields map[string]string, str string, float float64,
}
}
-func whereClauseStringValue(fields map[string]string, str string, t fieldType) (string, bool) {
+func whereClauseStringValue(fields map[string]string, str string,
+ t fieldType) (string, bool) {
+
switch t {
case Field:
value, ok := fields[str]
diff --git a/internal/mapr/wherecondition.go b/internal/mapr/wherecondition.go
index c60c0a5..280dcfb 100644
--- a/internal/mapr/wherecondition.go
+++ b/internal/mapr/wherecondition.go
@@ -46,15 +46,18 @@ type whereCondition struct {
}
func (wc *whereCondition) String() string {
- return fmt.Sprintf("whereCondition(Operation:%v,lString:%s,lFloat:%v,lType:%s,rString:%s,rFloat:%v,rType:%s)",
- wc.Operation, wc.lString, wc.lFloat, wc.lType.String(), wc.rString, wc.rFloat, wc.rType.String())
+ return fmt.Sprintf("whereCondition(Operation:%v,lString:%s,lFloat:%v,"+
+ "lType:%s,rString:%s,rFloat:%v,rType:%s)",
+ wc.Operation, wc.lString, wc.lFloat, wc.lType.String(), wc.rString,
+ wc.rFloat, wc.rType.String())
}
func makeWhereConditions(tokens []token) (where []whereCondition, err error) {
parse := func(tokens []token) (whereCondition, []token, error) {
var wc whereCondition
if len(tokens) < 3 {
- return wc, nil, errors.New(invalidQuery + "Not enough arguments in 'where' clause")
+ err := errors.New(invalidQuery + "Not enough arguments in 'where' clause")
+ return wc, nil, err
}
whereOp := strings.ToLower(tokens[1].str)
@@ -94,7 +97,8 @@ func makeWhereConditions(tokens []token) (where []whereCondition, err error) {
case "nhassuffix":
wc.Operation = StringNotHasSuffix
default:
- return wc, nil, errors.New(invalidQuery + "Unknown operation in 'where' clause: " + whereOp)
+ return wc, nil, errors.New(invalidQuery +
+ "Unknown operation in 'where' clause: " + whereOp)
}
wc.lString = tokens[0].str
@@ -102,7 +106,8 @@ func makeWhereConditions(tokens []token) (where []whereCondition, err error) {
if wc.Operation > FloatOperation {
if !tokens[0].isBareword {
- return wc, nil, errors.New(invalidQuery + "Expected bareword at 'where' clause's lValue: " + tokens[0].str)
+ return wc, nil, errors.New(invalidQuery +
+ "Expected bareword at 'where' clause's lValue: " + tokens[0].str)
}
if f, err := strconv.ParseFloat(wc.lString, 64); err == nil {
wc.lFloat = f
@@ -112,7 +117,8 @@ func makeWhereConditions(tokens []token) (where []whereCondition, err error) {
}
if !tokens[2].isBareword {
- return wc, nil, errors.New(invalidQuery + "Expected bareword at 'where' clause's rValue: " + tokens[2].str)
+ return wc, nil, errors.New(invalidQuery +
+ "Expected bareword at 'where' clause's rValue: " + tokens[2].str)
}
if f, err := strconv.ParseFloat(wc.rString, 64); err == nil {
wc.rFloat = f
@@ -133,23 +139,19 @@ func makeWhereConditions(tokens []token) (where []whereCondition, err error) {
} else {
wc.rType = String
}
-
return wc, tokens[3:], nil
}
for len(tokens) > 0 {
var wc whereCondition
var err error
-
wc, tokens, err = parse(tokens)
if err != nil {
return nil, err
}
-
where = append(where, wc)
tokens = tokensConsumeOptional(tokens, "and")
}
-
return
}
@@ -170,7 +172,6 @@ func (wc *whereCondition) floatClause(lValue float64, rValue float64) bool {
default:
dlog.Common.Error("Unknown float operation", lValue, wc.Operation, rValue)
}
-
return false
}
@@ -195,6 +196,5 @@ func (wc *whereCondition) stringClause(lValue string, rValue string) bool {
default:
dlog.Common.Error("Unknown string operation", lValue, wc.Operation, rValue)
}
-
return false
}