diff --git a/pkg/unify-query/internal/querystring/expr.go b/pkg/unify-query/internal/querystring/expr.go new file mode 100644 index 000000000..b9e8ea175 --- /dev/null +++ b/pkg/unify-query/internal/querystring/expr.go @@ -0,0 +1,174 @@ +// Tencent is pleased to support the open source community by making +// 蓝鲸智云 - 监控平台 (BlueKing - Monitor) available. +// Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. +// Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://opensource.org/licenses/MIT +// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +package querystring + +import ( + "strings" + "time" +) + +// Expr . +type Expr interface { +} + +// AndExpr . +type AndExpr struct { + Left Expr + Right Expr +} + +// NewAndExpr . +func NewAndExpr(left, right Expr) *AndExpr { + return &AndExpr{Left: left, Right: right} +} + +// OrExpr . +type OrExpr struct { + Left Expr + Right Expr +} + +// NewOrExpr . +func NewOrExpr(left, right Expr) *OrExpr { + return &OrExpr{Left: left, Right: right} +} + +// NotExpr . +type NotExpr struct { + Expr Expr +} + +// NewNotExpr . +func NewNotExpr(q Expr) *NotExpr { + return &NotExpr{Expr: q} +} + +// FieldableExpr . +type FieldableExpr interface { + SetField(field string) +} + +// MatchExpr . +type MatchExpr struct { + Field string + Value string +} + +// NewMatchExpr . +func NewMatchExpr(s string) *MatchExpr { + return &MatchExpr{ + Value: s, + } +} + +// SetField . +func (q *MatchExpr) SetField(field string) { + q.Field = field +} + +// RegexpExpr . +type RegexpExpr struct { + Field string + Value string +} + +// NewRegexpExpr . +func NewRegexpExpr(s string) *RegexpExpr { + return &RegexpExpr{ + Value: s, + } +} + +// SetField . +func (q *RegexpExpr) SetField(field string) { + q.Field = field +} + +// WildcardExpr . +type WildcardExpr struct { + Field string + Value string +} + +// NewWildcardExpr . +func NewWildcardExpr(s string) *WildcardExpr { + return &WildcardExpr{ + Value: s, + } +} + +// SetField . +func (q *WildcardExpr) SetField(field string) { + q.Field = field +} + +// NumberRangeExpr . +type NumberRangeExpr struct { + Field string + Start *string + End *string + IncludeStart bool + IncludeEnd bool +} + +// NewNumberRangeExpr . +func NewNumberRangeExpr(start, end *string, includeStart, includeEnd bool) *NumberRangeExpr { + return &NumberRangeExpr{ + Start: start, + End: end, + IncludeStart: includeStart, + IncludeEnd: includeEnd, + } +} + +// SetField . +func (q *NumberRangeExpr) SetField(field string) { + q.Field = field +} + +// TimeRangeExpr . +type TimeRangeExpr struct { + Field string + Start *string + End *string + IncludeStart bool + IncludeEnd bool +} + +// NewTimeRangeExpr . +func NewTimeRangeExpr(start, end *string, includeStart, includeEnd bool) *TimeRangeExpr { + return &TimeRangeExpr{ + Start: start, + End: end, + IncludeStart: includeStart, + IncludeEnd: includeEnd, + } +} + +// SetField . +func (q *TimeRangeExpr) SetField(field string) { + q.Field = field +} + +func queryTimeFromString(t string) (time.Time, error) { + return time.Parse(time.RFC3339, t) +} + +func newStringExpr(str string) FieldableExpr { + if strings.HasPrefix(str, "/") && strings.HasSuffix(str, "/") { + return NewRegexpExpr(str[1 : len(str)-1]) + } + + if strings.ContainsAny(str, "*?") { + return NewWildcardExpr(str) + } + + return NewMatchExpr(str) +} diff --git a/pkg/unify-query/internal/querystring/lex.go b/pkg/unify-query/internal/querystring/lex.go new file mode 100644 index 000000000..3f62e1bb1 --- /dev/null +++ b/pkg/unify-query/internal/querystring/lex.go @@ -0,0 +1,317 @@ +// Copyright (c) 2016 Couchbase, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package querystring + +import ( + "bufio" + "bytes" + "io" + "strings" + "unicode" +) + +const reservedChars = "+-=&|>', '<', '=', '(', ')', '[', ']', '{', '}', '*': + l.buf += string(next) + return singleCharOpState, true + } + + switch { + case !l.inEscape && next == '\\': + l.inEscape = true + return startState, true + case unicode.IsDigit(next): + l.buf += string(next) + return inNumOrStrState, true + case !unicode.IsSpace(next): + l.buf += string(next) + return inStrState, true + } + + // doesn't look like anything, just eat it and stay here + l.reset() + return startState, true +} + +func inPhraseState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + // unterminated phrase eats the phrase + if eof { + l.Error("unterminated quote") + return nil, false + } + + // only a non-escaped " ends the phrase + if !l.inEscape && (next == '"' || next == '/') { + // end phrase + switch next { + case '"': + l.nextTokenType = tPHRASE + case '/': + l.nextTokenType = tSLASH + } + l.nextToken = &yySymType{ + s: l.buf, + } + //log.Debugf(context.TODO(), "PHRASE - '%s'", l.nextToken.s) + l.reset() + return startState, true + } else if !l.inEscape && next == '\\' { + l.inEscape = true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + } else { + l.buf += string(next) + } + + return inPhraseState, true +} + +func singleCharOpState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + l.nextToken = &yySymType{} + + var msg bytes.Buffer + msg.WriteString(l.buf) + msg.WriteString(" => ") + switch l.buf { + case "+": + l.nextTokenType = tPLUS + msg.WriteString("tPLUS") + case "-": + l.nextTokenType = tMINUS + msg.WriteString("tMINUS") + case ":": + l.nextTokenType = tCOLON + msg.WriteString("tCOLON") + case ">": + l.nextTokenType = tGREATER + msg.WriteString("tGREATER") + case "<": + l.nextTokenType = tLESS + msg.WriteString("tLESS") + case "=": + l.nextTokenType = tEQUAL + msg.WriteString("tEQUAL") + case "(": + l.nextTokenType = tLEFTBRACKET + msg.WriteString("tLEFTBRACKET") + case ")": + l.nextTokenType = tRIGHTBRACKET + msg.WriteString("tRIGHTBRACKET") + case "[": + l.nextTokenType = tLEFTRANGE + msg.WriteString("tLEFTRANGE") + case "]": + l.nextTokenType = tRIGHTRANGE + msg.WriteString("tRIGHTRANGE") + case "{": + l.nextTokenType = tLEFTBRACES + msg.WriteString("tLEFTBRACES") + case "}": + l.nextTokenType = tRIGHTBRACES + msg.WriteString("tRIGHTBRACES") + case "*": + l.nextTokenType = tSTAR + msg.WriteString("tSTAR") + } + //log.Debugf(context.TODO(), msg.String()) + + l.reset() + return startState, false +} + +func inNumOrStrState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + // only a non-escaped space ends the tilde (or eof) + if eof || (!l.inEscape && next == ' ' || next == ':' || next == ')' || next == ']' || next == '}') { + // end number + consumed := true + if !eof && (next == ':' || next == ')' || next == ']' || next == '}') { + consumed = false + } + + l.nextTokenType = tNUMBER + l.nextToken = &yySymType{ + s: l.buf, + } + //log.Debugf(context.TODO(), "NUMBER - '%s'", l.nextToken.s) + l.reset() + return startState, consumed + } else if !l.inEscape && next == '\\' { + l.inEscape = true + return inNumOrStrState, true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + // go directly to string, no successfully or unsuccessfully + // escaped string results in a valid number + return inStrState, true + } + + // see where to go + if !l.seenDot && next == '.' { + // stay in this state + l.seenDot = true + l.buf += string(next) + return inNumOrStrState, true + } else if unicode.IsDigit(next) { + l.buf += string(next) + return inNumOrStrState, true + } + + // doesn't look like an number, transition + l.buf += string(next) + return inStrState, true +} + +func inStrState(l *queryStringLex, next rune, eof bool) (lexState, bool) { + // end on non-escped space, colon, tilde, boost (or eof) + if eof || (!l.inEscape && (next == ' ' || next == ':' || next == ')' || next == ']')) { + // end string + consumed := true + if !eof && (next == ':' || next == ')' || next == ']') { + consumed = false + } + + switch strings.ToLower(l.buf) { + case "and": + l.nextTokenType = tAND + l.nextToken = &yySymType{} + l.reset() + return startState, consumed + case "or": + l.nextTokenType = tOR + l.nextToken = &yySymType{} + l.reset() + return startState, consumed + case "not": + l.nextTokenType = tNOT + l.nextToken = &yySymType{} + l.reset() + return startState, consumed + case "to": + l.nextTokenType = tTO + l.nextToken = &yySymType{} + l.reset() + return startState, consumed + } + + l.nextTokenType = tSTRING + l.nextToken = &yySymType{ + s: l.buf, + } + //log.Debugf(context.TODO(), "STRING - '%s'", l.nextToken.s) + l.reset() + + return startState, consumed + } else if !l.inEscape && next == '\\' { + l.inEscape = true + } else if l.inEscape { + // if in escape, end it + l.inEscape = false + l.buf += unescape(string(next)) + } else { + l.buf += string(next) + } + + return inStrState, true +} diff --git a/pkg/unify-query/internal/querystring/parser.go b/pkg/unify-query/internal/querystring/parser.go new file mode 100644 index 000000000..998ae80a1 --- /dev/null +++ b/pkg/unify-query/internal/querystring/parser.go @@ -0,0 +1,74 @@ +// Tencent is pleased to support the open source community by making +// 蓝鲸智云 - 监控平台 (BlueKing - Monitor) available. +// Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. +// Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://opensource.org/licenses/MIT +// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +package querystring + +//go:generate goyacc -o querystring.y.go querystring.y + +import ( + "fmt" + "strings" +) + +// Parse querystring and return Expr +func Parse(query string) (Expr, error) { + if query == "" { + return nil, nil + } + + lex := newLexerWrapper(newExprStringLex(strings.NewReader(query))) + doParse(lex) + + if len(lex.errs) > 0 { + return nil, fmt.Errorf(strings.Join(lex.errs, "\n")) + } + return lex.expr, nil +} + +func doParse(lex *lexerWrapper) { + defer func() { + r := recover() + if r != nil { + lex.errs = append(lex.errs, fmt.Sprintf("parse error: %v", r)) + } + }() + + yyParse(lex) +} + +const ( + queryShould = iota + queryMust + queryMustNot +) + +type lexerWrapper struct { + lex yyLexer + errs []string + expr Expr +} + +func newLexerWrapper(lex yyLexer) *lexerWrapper { + return &lexerWrapper{ + lex: lex, + expr: nil, + } +} + +func (l *lexerWrapper) Lex(lval *yySymType) int { + return l.lex.Lex(lval) +} + +func (l *lexerWrapper) Error(s string) { + l.errs = append(l.errs, s) +} + +func init() { + yyErrorVerbose = true +} diff --git a/pkg/unify-query/internal/querystring/parser_test.go b/pkg/unify-query/internal/querystring/parser_test.go new file mode 100644 index 000000000..fa7187264 --- /dev/null +++ b/pkg/unify-query/internal/querystring/parser_test.go @@ -0,0 +1,289 @@ +// Tencent is pleased to support the open source community by making +// 蓝鲸智云 - 监控平台 (BlueKing - Monitor) available. +// Copyright (C) 2022 THL A29 Limited, a Tencent company. All rights reserved. +// Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +// You may obtain a copy of the License at http://opensource.org/licenses/MIT +// Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +// specific language governing permissions and limitations under the License. + +package querystring + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/TencentBlueKing/bkmonitor-datalink/pkg/unify-query/metadata" + "github.com/TencentBlueKing/bkmonitor-datalink/pkg/unify-query/mock" +) + +/* +精确匹配(支持AND、OR): +author:"John Smith" AND age:20 +字段名匹配(*代表通配符): +status:active +title:(quick brown) +字段名模糊匹配: +vers\*on:(quick brown) +通配符匹配: +qu?ck bro* +正则匹配: +name:/joh?n(ath[oa]n)/ +范围匹配: +count:[1 TO 5] +count:[1 TO 5} +count:[10 TO *] +*/ +func TestParser(t *testing.T) { + testCases := map[string]struct { + q string + e Expr + }{ + "正常查询": { + q: `test`, + e: &MatchExpr{ + Value: `test`, + }, + }, + "负数查询": { + q: `-test`, + e: &NotExpr{ + Expr: &MatchExpr{ + Value: `test`, + }, + }, + }, + "负数查询多条件": { + q: `-test AND good`, + e: &AndExpr{ + Left: &NotExpr{ + Expr: &MatchExpr{ + Value: `test`, + }, + }, + Right: &MatchExpr{ + Value: `good`, + }, + }, + }, + "通配符匹配": { + q: `qu?ck bro*`, + e: &OrExpr{ + Left: &WildcardExpr{ + Value: "qu?ck", + }, + Right: &WildcardExpr{ + Value: "bro*", + }, + }, + }, + "正则匹配": { + q: `name:/joh?n(ath[oa]n)/`, + e: &RegexpExpr{ + Field: "name", + Value: "joh?n(ath[oa]n)", + }, + }, + "范围匹配,左闭右开": { + q: `count:[1 TO 5}`, + e: &NumberRangeExpr{ + Field: "count", + Start: pointer("1"), + End: pointer("5"), + IncludeStart: true, + IncludeEnd: false, + }, + }, + "范围匹配": { + q: `count:[1 TO 5]`, + e: &NumberRangeExpr{ + Field: "count", + Start: pointer("1"), + End: pointer("5"), + IncludeStart: true, + IncludeEnd: true, + }, + }, + "范围匹配(无上限)": { + q: `count:[10 TO *]`, + e: &NumberRangeExpr{ + Field: "count", + Start: pointer("10"), + IncludeStart: true, + IncludeEnd: true, + }, + }, + "字段匹配": { + q: `status:active`, + e: &MatchExpr{ + Field: "status", + Value: "active", + }, + }, + "字段匹配 + 括号": { + q: `status:(active)`, + e: &MatchExpr{ + Field: "status", + Value: "active", + }, + }, + "多条件组合,括号调整优先级": { + q: `author:"John Smith" AND (age:20 OR status:active)`, + e: &AndExpr{ + Left: &MatchExpr{ + Field: "author", + Value: "John Smith", + }, + Right: &OrExpr{ + Left: &MatchExpr{ + Field: "age", + Value: "20", + }, + Right: &MatchExpr{ + Field: "status", + Value: "active", + }, + }, + }, + }, + "多条件组合,and 和 or 的优先级": { + q: `(author:"John Smith" AND age:20) OR status:active`, + e: &OrExpr{ + Left: &AndExpr{ + Left: &MatchExpr{ + Field: "author", + Value: "John Smith", + }, + Right: &MatchExpr{ + Field: "age", + Value: "20", + }, + }, + Right: &MatchExpr{ + Field: "status", + Value: "active", + }, + }, + }, + "嵌套逻辑表达式": { + q: `a:1 AND (b:2 OR c:3)`, + e: &AndExpr{ + Left: &MatchExpr{ + Field: "a", + Value: "1", + }, + Right: &OrExpr{ + Left: &MatchExpr{ + Field: "b", + Value: "2", + }, + Right: &MatchExpr{ + Field: "c", + Value: "3", + }, + }, + }, + }, + "new-1": { + q: `quick brown +fox -news`, + e: &OrExpr{ + Left: &MatchExpr{ + Value: "quick", + }, + Right: &OrExpr{ + Left: &MatchExpr{ + Value: "brown", + }, + Right: &OrExpr{ + Left: &MatchExpr{ + Value: "fox", + }, + Right: &NotExpr{ + Expr: &MatchExpr{ + Field: "", + Value: "news", + }, + }, + }, + }, + }, + }, + "模糊匹配": { + q: `quick brown fox`, + e: &OrExpr{ + Left: &MatchExpr{ + Value: "quick", + }, + Right: &OrExpr{ + Left: &MatchExpr{ + Value: "brown", + }, + Right: &MatchExpr{ + Value: "fox", + }, + }, + }, + }, + "单个条件精确匹配": { + q: `log: "ERROR MSG"`, + e: &MatchExpr{ + Field: "log", + Value: "ERROR MSG", + }, + }, + "match and time range": { + q: "message: test\\ value AND datetime: [\"2020-01-01T00:00:00\" TO \"2020-12-31T00:00:00\"]", + e: &AndExpr{ + Left: &MatchExpr{ + Field: "message", + Value: "test value", + }, + Right: &TimeRangeExpr{ + Field: "datetime", + Start: pointer("2020-01-01T00:00:00"), + End: pointer("2020-12-31T00:00:00"), + IncludeStart: true, + IncludeEnd: true, + }, + }, + }, + "mixed or / and": { + q: "a: 1 OR (b: 2 and c: 4)", + e: &OrExpr{ + Left: &MatchExpr{ + Field: "a", + Value: "1", + }, + Right: &AndExpr{ + Left: &MatchExpr{ + Field: "b", + Value: "2", + }, + Right: &MatchExpr{ + Field: "c", + Value: "4", + }, + }, + }, + }, + } + + metadata.InitMetadata() + mock.Init() + + for name, c := range testCases { + t.Run(name, func(t *testing.T) { + expr, err := Parse(c.q) + if err != nil { + t.Errorf("parse return error, %s", err) + return + } + assert.Equal(t, c.e, expr) + }) + } +} + +func pointer(s string) *string { + return &s +} diff --git a/pkg/unify-query/internal/querystring/querystring.y b/pkg/unify-query/internal/querystring/querystring.y new file mode 100644 index 000000000..377925eaa --- /dev/null +++ b/pkg/unify-query/internal/querystring/querystring.y @@ -0,0 +1,270 @@ +%{ +package querystring +%} + +%union { + s string + n int + e Expr +} + +%token tSTRING tPHRASE tNUMBER tSLASH tSTAR +%token tOR tAND tNOT tTO tPLUS tMINUS tCOLON +%token tLEFTBRACKET tRIGHTBRACKET tLEFTRANGE tRIGHTRANGE tLEFTBRACES tRIGHTBRACES +%token tGREATER tLESS tEQUAL + +%type tSTRING +%type tPHRASE +%type tNUMBER +%type tSTAR +%type tSLASH +%type posOrNegNumber +%type searchBase searchLogicParts searchPart searchLogicPart searchLogicSimplePart +%type searchPrefix + +%left tOR +%left tAND +%nonassoc tLEFTBRACKET tRIGHTBRACKET + +%% + +input: +searchLogicParts { + yylex.(*lexerWrapper).expr = $1 +}; + +searchLogicParts: +searchLogicPart searchLogicParts { + $$ = NewOrExpr($1, $2) +} +| +searchLogicPart { + $$ = $1 +} + +searchLogicPart: +searchLogicSimplePart { + $$ = $1 +} +| +searchLogicSimplePart tOR searchLogicPart { + $$ = NewOrExpr($1, $3) +} +| +searchLogicSimplePart tAND searchLogicPart { + $$ = NewAndExpr($1, $3) +}; + +searchLogicSimplePart: +searchPart { + $$ = $1 +} +| +tLEFTBRACKET searchLogicPart tRIGHTBRACKET { + $$ = $2 +} +| +tNOT searchLogicSimplePart { + $$ = NewNotExpr($2) +}; + +searchPart: +searchPrefix searchBase { + switch($1) { + case queryMustNot: + $$ = NewNotExpr($2) + default: + $$ = $2 + } +} +| +searchBase { + $$ = $1 +}; + +searchPrefix: +tPLUS { + $$ = queryMust +} +| +tMINUS { + $$ = queryMustNot +}; + +searchBase: +tSTRING { + $$ = newStringExpr($1) +} +| +tNUMBER { + $$ = NewMatchExpr($1) +} +| +tPHRASE { + phrase := $1 + q := NewMatchExpr(phrase) + $$ = q +} +| +tSLASH{ + phrase := $1 + q := NewRegexpExpr(phrase) + $$ = q +} +| +tSTRING tCOLON tSTRING { + q := newStringExpr($3) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTBRACKET tSTRING tRIGHTBRACKET { + q := newStringExpr($4) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON posOrNegNumber { + q := NewMatchExpr($3) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tPHRASE { + q := NewMatchExpr($3) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tSLASH { + q := NewRegexpExpr($3) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tGREATER posOrNegNumber { + val := $4 + q := NewNumberRangeExpr(&val, nil, false, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tGREATER tEQUAL posOrNegNumber { + val := $5 + q := NewNumberRangeExpr(&val, nil, true, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLESS posOrNegNumber { + val := $4 + q := NewNumberRangeExpr(nil, &val, false, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLESS tEQUAL posOrNegNumber { + val := $5 + q := NewNumberRangeExpr(nil, &val, false, true) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tGREATER tPHRASE { + phrase := $4 + q := NewTimeRangeExpr(&phrase, nil, false, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tGREATER tEQUAL tPHRASE { + phrase := $5 + q := NewTimeRangeExpr(&phrase, nil, true, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLESS tPHRASE { + phrase := $4 + q := NewTimeRangeExpr(nil, &phrase, false, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLESS tEQUAL tPHRASE { + phrase := $5 + q := NewTimeRangeExpr(nil, &phrase, false, true) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTRANGE tSTAR tTO posOrNegNumber tRIGHTRANGE { + max := $6 + q := NewNumberRangeExpr(nil, &max, true, true) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO tSTAR tRIGHTRANGE { + min := $4 + q := NewNumberRangeExpr(&min, nil, true, true) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTBRACES { + min := $4 + max := $6 + q := NewNumberRangeExpr(&min, &max, true, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTBRACES { + min := $4 + max := $6 + q := NewTimeRangeExpr(&min, &max, true, false) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTBRACES posOrNegNumber tTO posOrNegNumber tRIGHTRANGE { + min := $4 + max := $6 + q := NewNumberRangeExpr(&min, &max, false, true) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTBRACES tPHRASE tTO tPHRASE tRIGHTRANGE { + min := $4 + max := $6 + q := NewTimeRangeExpr(&min, &max, false, true) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTRANGE { + min := $4 + max := $6 + q := NewNumberRangeExpr(&min, &max, true, true) + q.SetField($1) + $$ = q +} +| +tSTRING tCOLON tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTRANGE { + min := $4 + max := $6 + q := NewTimeRangeExpr(&min, &max, true, true) + q.SetField($1) + $$ = q +}; + +posOrNegNumber: +tNUMBER { + $$ = $1 +} +| +tMINUS tNUMBER { + $$ = "-" + $2 +}; diff --git a/pkg/unify-query/internal/querystring/querystring.y.go b/pkg/unify-query/internal/querystring/querystring.y.go new file mode 100644 index 000000000..86e619b3c --- /dev/null +++ b/pkg/unify-query/internal/querystring/querystring.y.go @@ -0,0 +1,816 @@ +// Code generated by goyacc -o querystring.y.go querystring.y. DO NOT EDIT. + +//line querystring.y:2 +package querystring + +import __yyfmt__ "fmt" + +//line querystring.y:2 + +//line querystring.y:5 +type yySymType struct { + yys int + s string + n int + e Expr +} + +const tSTRING = 57346 +const tPHRASE = 57347 +const tNUMBER = 57348 +const tSLASH = 57349 +const tSTAR = 57350 +const tOR = 57351 +const tAND = 57352 +const tNOT = 57353 +const tTO = 57354 +const tPLUS = 57355 +const tMINUS = 57356 +const tCOLON = 57357 +const tLEFTBRACKET = 57358 +const tRIGHTBRACKET = 57359 +const tLEFTRANGE = 57360 +const tRIGHTRANGE = 57361 +const tLEFTBRACES = 57362 +const tRIGHTBRACES = 57363 +const tGREATER = 57364 +const tLESS = 57365 +const tEQUAL = 57366 + +var yyToknames = [...]string{ + "$end", + "error", + "$unk", + "tSTRING", + "tPHRASE", + "tNUMBER", + "tSLASH", + "tSTAR", + "tOR", + "tAND", + "tNOT", + "tTO", + "tPLUS", + "tMINUS", + "tCOLON", + "tLEFTBRACKET", + "tRIGHTBRACKET", + "tLEFTRANGE", + "tRIGHTRANGE", + "tLEFTBRACES", + "tRIGHTBRACES", + "tGREATER", + "tLESS", + "tEQUAL", +} + +var yyStatenames = [...]string{} + +const yyEofCode = 1 +const yyErrCode = 2 +const yyInitialStackSize = 16 + +//line yacctab:1 +var yyExca = [...]int8{ + -1, 1, + 1, -1, + -2, 0, +} + +const yyPrivate = 57344 + +const yyLast = 93 + +var yyAct = [...]int8{ + 28, 26, 29, 35, 30, 43, 35, 40, 35, 73, + 71, 36, 70, 27, 36, 33, 36, 34, 72, 31, + 32, 22, 67, 69, 42, 68, 39, 66, 50, 3, + 25, 59, 38, 41, 45, 47, 19, 35, 35, 61, + 51, 46, 35, 53, 44, 36, 36, 23, 24, 58, + 36, 12, 14, 13, 15, 57, 60, 62, 7, 64, + 10, 11, 56, 6, 54, 35, 52, 35, 48, 35, + 55, 17, 18, 36, 9, 36, 4, 36, 12, 14, + 13, 15, 49, 21, 20, 65, 63, 37, 2, 1, + 8, 5, 16, +} + +var yyPact = [...]int16{ + 47, -1000, -1000, 47, 62, -1000, 47, 47, 74, -1000, + -1000, -1000, 6, -1000, -1000, -1000, -1000, 47, 47, 13, + -1000, -1000, -3, -1000, -1000, -1000, -1000, 83, -1000, -1000, + -1000, 2, 0, 36, 63, -1000, 76, 11, -1000, 61, + -1000, -1000, 59, -1000, 58, 50, 43, 37, 19, -1000, + -1000, -1000, -1000, -1000, -1000, 32, 31, 81, 32, 80, + 8, 3, 4, -9, -1, -10, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, +} + +var yyPgo = [...]int8{ + 0, 0, 74, 88, 91, 29, 76, 90, 89, +} + +var yyR1 = [...]int8{ + 0, 8, 3, 3, 5, 5, 5, 6, 6, 6, + 4, 4, 7, 7, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, +} + +var yyR2 = [...]int8{ + 0, 1, 2, 1, 1, 3, 3, 1, 3, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 3, 5, + 3, 3, 3, 4, 5, 4, 5, 4, 5, 4, + 5, 7, 7, 7, 7, 7, 7, 7, 7, 1, + 2, +} + +var yyChk = [...]int16{ + -1000, -8, -3, -5, -6, -4, 16, 11, -7, -2, + 13, 14, 4, 6, 5, 7, -3, 9, 10, -5, + -6, -2, 15, -5, -5, 17, 4, 16, -1, 5, + 7, 22, 23, 18, 20, 6, 14, 4, -1, 24, + 5, -1, 24, 5, 8, -1, 5, -1, 5, 6, + 17, -1, 5, -1, 5, 12, 12, 12, 12, 12, + -1, 8, -1, 5, -1, 5, 19, 19, 21, 19, + 21, 19, 19, 19, +} + +var yyDef = [...]int8{ + 0, -2, 1, 3, 4, 7, 0, 0, 0, 11, + 12, 13, 14, 15, 16, 17, 2, 0, 0, 0, + 9, 10, 0, 5, 6, 8, 18, 0, 20, 21, + 22, 0, 0, 0, 0, 39, 0, 0, 23, 0, + 27, 25, 0, 29, 0, 0, 0, 0, 0, 40, + 19, 24, 28, 26, 30, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 31, 32, 33, 37, + 34, 38, 35, 36, +} + +var yyTok1 = [...]int8{ + 1, +} + +var yyTok2 = [...]int8{ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, +} + +var yyTok3 = [...]int8{ + 0, +} + +var yyErrorMessages = [...]struct { + state int + token int + msg string +}{} + +//line yaccpar:1 + +/* parser for yacc output */ + +var ( + yyDebug = 0 + yyErrorVerbose = false +) + +type yyLexer interface { + Lex(lval *yySymType) int + Error(s string) +} + +type yyParser interface { + Parse(yyLexer) int + Lookahead() int +} + +type yyParserImpl struct { + lval yySymType + stack [yyInitialStackSize]yySymType + char int +} + +func (p *yyParserImpl) Lookahead() int { + return p.char +} + +func yyNewParser() yyParser { + return &yyParserImpl{} +} + +const yyFlag = -1000 + +func yyTokname(c int) string { + if c >= 1 && c-1 < len(yyToknames) { + if yyToknames[c-1] != "" { + return yyToknames[c-1] + } + } + return __yyfmt__.Sprintf("tok-%v", c) +} + +func yyStatname(s int) string { + if s >= 0 && s < len(yyStatenames) { + if yyStatenames[s] != "" { + return yyStatenames[s] + } + } + return __yyfmt__.Sprintf("state-%v", s) +} + +func yyErrorMessage(state, lookAhead int) string { + const TOKSTART = 4 + + if !yyErrorVerbose { + return "syntax error" + } + + for _, e := range yyErrorMessages { + if e.state == state && e.token == lookAhead { + return "syntax error: " + e.msg + } + } + + res := "syntax error: unexpected " + yyTokname(lookAhead) + + // To match Bison, suggest at most four expected tokens. + expected := make([]int, 0, 4) + + // Look for shiftable tokens. + base := int(yyPact[state]) + for tok := TOKSTART; tok-1 < len(yyToknames); tok++ { + if n := base + tok; n >= 0 && n < yyLast && int(yyChk[int(yyAct[n])]) == tok { + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + } + + if yyDef[state] == -2 { + i := 0 + for yyExca[i] != -1 || int(yyExca[i+1]) != state { + i += 2 + } + + // Look for tokens that we accept or reduce. + for i += 2; yyExca[i] >= 0; i += 2 { + tok := int(yyExca[i]) + if tok < TOKSTART || yyExca[i+1] == 0 { + continue + } + if len(expected) == cap(expected) { + return res + } + expected = append(expected, tok) + } + + // If the default action is to accept or reduce, give up. + if yyExca[i+1] != 0 { + return res + } + } + + for i, tok := range expected { + if i == 0 { + res += ", expecting " + } else { + res += " or " + } + res += yyTokname(tok) + } + return res +} + +func yylex1(lex yyLexer, lval *yySymType) (char, token int) { + token = 0 + char = lex.Lex(lval) + if char <= 0 { + token = int(yyTok1[0]) + goto out + } + if char < len(yyTok1) { + token = int(yyTok1[char]) + goto out + } + if char >= yyPrivate { + if char < yyPrivate+len(yyTok2) { + token = int(yyTok2[char-yyPrivate]) + goto out + } + } + for i := 0; i < len(yyTok3); i += 2 { + token = int(yyTok3[i+0]) + if token == char { + token = int(yyTok3[i+1]) + goto out + } + } + +out: + if token == 0 { + token = int(yyTok2[1]) /* unknown char */ + } + if yyDebug >= 3 { + __yyfmt__.Printf("lex %s(%d)\n", yyTokname(token), uint(char)) + } + return char, token +} + +func yyParse(yylex yyLexer) int { + return yyNewParser().Parse(yylex) +} + +func (yyrcvr *yyParserImpl) Parse(yylex yyLexer) int { + var yyn int + var yyVAL yySymType + var yyDollar []yySymType + _ = yyDollar // silence set and not used + yyS := yyrcvr.stack[:] + + Nerrs := 0 /* number of errors */ + Errflag := 0 /* error recovery flag */ + yystate := 0 + yyrcvr.char = -1 + yytoken := -1 // yyrcvr.char translated into internal numbering + defer func() { + // Make sure we report no lookahead when not parsing. + yystate = -1 + yyrcvr.char = -1 + yytoken = -1 + }() + yyp := -1 + goto yystack + +ret0: + return 0 + +ret1: + return 1 + +yystack: + /* put a state and value onto the stack */ + if yyDebug >= 4 { + __yyfmt__.Printf("char %v in %v\n", yyTokname(yytoken), yyStatname(yystate)) + } + + yyp++ + if yyp >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyS[yyp] = yyVAL + yyS[yyp].yys = yystate + +yynewstate: + yyn = int(yyPact[yystate]) + if yyn <= yyFlag { + goto yydefault /* simple state */ + } + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + yyn += yytoken + if yyn < 0 || yyn >= yyLast { + goto yydefault + } + yyn = int(yyAct[yyn]) + if int(yyChk[yyn]) == yytoken { /* valid shift */ + yyrcvr.char = -1 + yytoken = -1 + yyVAL = yyrcvr.lval + yystate = yyn + if Errflag > 0 { + Errflag-- + } + goto yystack + } + +yydefault: + /* default state action */ + yyn = int(yyDef[yystate]) + if yyn == -2 { + if yyrcvr.char < 0 { + yyrcvr.char, yytoken = yylex1(yylex, &yyrcvr.lval) + } + + /* look through exception table */ + xi := 0 + for { + if yyExca[xi+0] == -1 && int(yyExca[xi+1]) == yystate { + break + } + xi += 2 + } + for xi += 2; ; xi += 2 { + yyn = int(yyExca[xi+0]) + if yyn < 0 || yyn == yytoken { + break + } + } + yyn = int(yyExca[xi+1]) + if yyn < 0 { + goto ret0 + } + } + if yyn == 0 { + /* error ... attempt to resume parsing */ + switch Errflag { + case 0: /* brand new error */ + yylex.Error(yyErrorMessage(yystate, yytoken)) + Nerrs++ + if yyDebug >= 1 { + __yyfmt__.Printf("%s", yyStatname(yystate)) + __yyfmt__.Printf(" saw %s\n", yyTokname(yytoken)) + } + fallthrough + + case 1, 2: /* incompletely recovered error ... try again */ + Errflag = 3 + + /* find a state where "error" is a legal shift action */ + for yyp >= 0 { + yyn = int(yyPact[yyS[yyp].yys]) + yyErrCode + if yyn >= 0 && yyn < yyLast { + yystate = int(yyAct[yyn]) /* simulate a shift of "error" */ + if int(yyChk[yystate]) == yyErrCode { + goto yystack + } + } + + /* the current p has no shift on "error", pop stack */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys) + } + yyp-- + } + /* there is no state on the stack with an error shift ... abort */ + goto ret1 + + case 3: /* no shift yet; clobber input char */ + if yyDebug >= 2 { + __yyfmt__.Printf("error recovery discards %s\n", yyTokname(yytoken)) + } + if yytoken == yyEofCode { + goto ret1 + } + yyrcvr.char = -1 + yytoken = -1 + goto yynewstate /* try again in the same state */ + } + } + + /* reduction by production yyn */ + if yyDebug >= 2 { + __yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate)) + } + + yynt := yyn + yypt := yyp + _ = yypt // guard against "declared and not used" + + yyp -= int(yyR2[yyn]) + // yyp is now the index of $0. Perform the default action. Iff the + // reduced production is ε, $1 is possibly out of range. + if yyp+1 >= len(yyS) { + nyys := make([]yySymType, len(yyS)*2) + copy(nyys, yyS) + yyS = nyys + } + yyVAL = yyS[yyp+1] + + /* consult goto table to find next state */ + yyn = int(yyR1[yyn]) + yyg := int(yyPgo[yyn]) + yyj := yyg + yyS[yyp].yys + 1 + + if yyj >= yyLast { + yystate = int(yyAct[yyg]) + } else { + yystate = int(yyAct[yyj]) + if int(yyChk[yystate]) != -yyn { + yystate = int(yyAct[yyg]) + } + } + // dummy call; replaced with literal code + switch yynt { + + case 1: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:32 + { + yylex.(*lexerWrapper).expr = yyDollar[1].e + } + case 2: + yyDollar = yyS[yypt-2 : yypt+1] +//line querystring.y:37 + { + yyVAL.e = NewOrExpr(yyDollar[1].e, yyDollar[2].e) + } + case 3: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:41 + { + yyVAL.e = yyDollar[1].e + } + case 4: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:46 + { + yyVAL.e = yyDollar[1].e + } + case 5: + yyDollar = yyS[yypt-3 : yypt+1] +//line querystring.y:50 + { + yyVAL.e = NewOrExpr(yyDollar[1].e, yyDollar[3].e) + } + case 6: + yyDollar = yyS[yypt-3 : yypt+1] +//line querystring.y:54 + { + yyVAL.e = NewAndExpr(yyDollar[1].e, yyDollar[3].e) + } + case 7: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:59 + { + yyVAL.e = yyDollar[1].e + } + case 8: + yyDollar = yyS[yypt-3 : yypt+1] +//line querystring.y:63 + { + yyVAL.e = yyDollar[2].e + } + case 9: + yyDollar = yyS[yypt-2 : yypt+1] +//line querystring.y:67 + { + yyVAL.e = NewNotExpr(yyDollar[2].e) + } + case 10: + yyDollar = yyS[yypt-2 : yypt+1] +//line querystring.y:72 + { + switch yyDollar[1].n { + case queryMustNot: + yyVAL.e = NewNotExpr(yyDollar[2].e) + default: + yyVAL.e = yyDollar[2].e + } + } + case 11: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:81 + { + yyVAL.e = yyDollar[1].e + } + case 12: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:86 + { + yyVAL.n = queryMust + } + case 13: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:90 + { + yyVAL.n = queryMustNot + } + case 14: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:95 + { + yyVAL.e = newStringExpr(yyDollar[1].s) + } + case 15: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:99 + { + yyVAL.e = NewMatchExpr(yyDollar[1].s) + } + case 16: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:103 + { + phrase := yyDollar[1].s + q := NewMatchExpr(phrase) + yyVAL.e = q + } + case 17: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:109 + { + phrase := yyDollar[1].s + q := NewRegexpExpr(phrase) + yyVAL.e = q + } + case 18: + yyDollar = yyS[yypt-3 : yypt+1] +//line querystring.y:115 + { + q := newStringExpr(yyDollar[3].s) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 19: + yyDollar = yyS[yypt-5 : yypt+1] +//line querystring.y:121 + { + q := newStringExpr(yyDollar[4].s) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 20: + yyDollar = yyS[yypt-3 : yypt+1] +//line querystring.y:127 + { + q := NewMatchExpr(yyDollar[3].s) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 21: + yyDollar = yyS[yypt-3 : yypt+1] +//line querystring.y:133 + { + q := NewMatchExpr(yyDollar[3].s) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 22: + yyDollar = yyS[yypt-3 : yypt+1] +//line querystring.y:139 + { + q := NewRegexpExpr(yyDollar[3].s) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 23: + yyDollar = yyS[yypt-4 : yypt+1] +//line querystring.y:145 + { + val := yyDollar[4].s + q := NewNumberRangeExpr(&val, nil, false, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 24: + yyDollar = yyS[yypt-5 : yypt+1] +//line querystring.y:152 + { + val := yyDollar[5].s + q := NewNumberRangeExpr(&val, nil, true, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 25: + yyDollar = yyS[yypt-4 : yypt+1] +//line querystring.y:159 + { + val := yyDollar[4].s + q := NewNumberRangeExpr(nil, &val, false, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 26: + yyDollar = yyS[yypt-5 : yypt+1] +//line querystring.y:166 + { + val := yyDollar[5].s + q := NewNumberRangeExpr(nil, &val, false, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 27: + yyDollar = yyS[yypt-4 : yypt+1] +//line querystring.y:173 + { + phrase := yyDollar[4].s + q := NewTimeRangeExpr(&phrase, nil, false, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 28: + yyDollar = yyS[yypt-5 : yypt+1] +//line querystring.y:180 + { + phrase := yyDollar[5].s + q := NewTimeRangeExpr(&phrase, nil, true, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 29: + yyDollar = yyS[yypt-4 : yypt+1] +//line querystring.y:187 + { + phrase := yyDollar[4].s + q := NewTimeRangeExpr(nil, &phrase, false, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 30: + yyDollar = yyS[yypt-5 : yypt+1] +//line querystring.y:194 + { + phrase := yyDollar[5].s + q := NewTimeRangeExpr(nil, &phrase, false, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 31: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:201 + { + max := yyDollar[6].s + q := NewNumberRangeExpr(nil, &max, true, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 32: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:208 + { + min := yyDollar[4].s + q := NewNumberRangeExpr(&min, nil, true, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 33: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:215 + { + min := yyDollar[4].s + max := yyDollar[6].s + q := NewNumberRangeExpr(&min, &max, true, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 34: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:223 + { + min := yyDollar[4].s + max := yyDollar[6].s + q := NewTimeRangeExpr(&min, &max, true, false) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 35: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:231 + { + min := yyDollar[4].s + max := yyDollar[6].s + q := NewNumberRangeExpr(&min, &max, false, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 36: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:239 + { + min := yyDollar[4].s + max := yyDollar[6].s + q := NewTimeRangeExpr(&min, &max, false, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 37: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:247 + { + min := yyDollar[4].s + max := yyDollar[6].s + q := NewNumberRangeExpr(&min, &max, true, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 38: + yyDollar = yyS[yypt-7 : yypt+1] +//line querystring.y:255 + { + min := yyDollar[4].s + max := yyDollar[6].s + q := NewTimeRangeExpr(&min, &max, true, true) + q.SetField(yyDollar[1].s) + yyVAL.e = q + } + case 39: + yyDollar = yyS[yypt-1 : yypt+1] +//line querystring.y:264 + { + yyVAL.s = yyDollar[1].s + } + case 40: + yyDollar = yyS[yypt-2 : yypt+1] +//line querystring.y:268 + { + yyVAL.s = "-" + yyDollar[2].s + } + } + goto yystack /* stack new state and value */ +} diff --git a/pkg/unify-query/internal/querystring/y.output b/pkg/unify-query/internal/querystring/y.output new file mode 100644 index 000000000..7c82715fc --- /dev/null +++ b/pkg/unify-query/internal/querystring/y.output @@ -0,0 +1,679 @@ + +state 0 + $accept: .input $end + + tSTRING shift 12 + tPHRASE shift 14 + tNUMBER shift 13 + tSLASH shift 15 + tNOT shift 7 + tPLUS shift 10 + tMINUS shift 11 + tLEFTBRACKET shift 6 + . error + + searchBase goto 9 + searchLogicParts goto 2 + searchPart goto 5 + searchLogicPart goto 3 + searchLogicSimplePart goto 4 + searchPrefix goto 8 + input goto 1 + +state 1 + $accept: input.$end + + $end accept + . error + + +state 2 + input: searchLogicParts. (1) + + . reduce 1 (src line 31) + + +state 3 + searchLogicParts: searchLogicPart.searchLogicParts + searchLogicParts: searchLogicPart. (3) + + tSTRING shift 12 + tPHRASE shift 14 + tNUMBER shift 13 + tSLASH shift 15 + tNOT shift 7 + tPLUS shift 10 + tMINUS shift 11 + tLEFTBRACKET shift 6 + . reduce 3 (src line 40) + + searchBase goto 9 + searchLogicParts goto 16 + searchPart goto 5 + searchLogicPart goto 3 + searchLogicSimplePart goto 4 + searchPrefix goto 8 + +state 4 + searchLogicPart: searchLogicSimplePart. (4) + searchLogicPart: searchLogicSimplePart.tOR searchLogicPart + searchLogicPart: searchLogicSimplePart.tAND searchLogicPart + + tOR shift 17 + tAND shift 18 + . reduce 4 (src line 45) + + +state 5 + searchLogicSimplePart: searchPart. (7) + + . reduce 7 (src line 58) + + +state 6 + searchLogicSimplePart: tLEFTBRACKET.searchLogicPart tRIGHTBRACKET + + tSTRING shift 12 + tPHRASE shift 14 + tNUMBER shift 13 + tSLASH shift 15 + tNOT shift 7 + tPLUS shift 10 + tMINUS shift 11 + tLEFTBRACKET shift 6 + . error + + searchBase goto 9 + searchPart goto 5 + searchLogicPart goto 19 + searchLogicSimplePart goto 4 + searchPrefix goto 8 + +state 7 + searchLogicSimplePart: tNOT.searchLogicSimplePart + + tSTRING shift 12 + tPHRASE shift 14 + tNUMBER shift 13 + tSLASH shift 15 + tNOT shift 7 + tPLUS shift 10 + tMINUS shift 11 + tLEFTBRACKET shift 6 + . error + + searchBase goto 9 + searchPart goto 5 + searchLogicSimplePart goto 20 + searchPrefix goto 8 + +state 8 + searchPart: searchPrefix.searchBase + + tSTRING shift 12 + tPHRASE shift 14 + tNUMBER shift 13 + tSLASH shift 15 + . error + + searchBase goto 21 + +state 9 + searchPart: searchBase. (11) + + . reduce 11 (src line 80) + + +state 10 + searchPrefix: tPLUS. (12) + + . reduce 12 (src line 85) + + +state 11 + searchPrefix: tMINUS. (13) + + . reduce 13 (src line 89) + + +state 12 + searchBase: tSTRING. (14) + searchBase: tSTRING.tCOLON tSTRING + searchBase: tSTRING.tCOLON tLEFTBRACKET tSTRING tRIGHTBRACKET + searchBase: tSTRING.tCOLON posOrNegNumber + searchBase: tSTRING.tCOLON tPHRASE + searchBase: tSTRING.tCOLON tSLASH + searchBase: tSTRING.tCOLON tGREATER posOrNegNumber + searchBase: tSTRING.tCOLON tGREATER tEQUAL posOrNegNumber + searchBase: tSTRING.tCOLON tLESS posOrNegNumber + searchBase: tSTRING.tCOLON tLESS tEQUAL posOrNegNumber + searchBase: tSTRING.tCOLON tGREATER tPHRASE + searchBase: tSTRING.tCOLON tGREATER tEQUAL tPHRASE + searchBase: tSTRING.tCOLON tLESS tPHRASE + searchBase: tSTRING.tCOLON tLESS tEQUAL tPHRASE + searchBase: tSTRING.tCOLON tLEFTRANGE tSTAR tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING.tCOLON tLEFTRANGE posOrNegNumber tTO tSTAR tRIGHTRANGE + searchBase: tSTRING.tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTBRACES + searchBase: tSTRING.tCOLON tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTBRACES + searchBase: tSTRING.tCOLON tLEFTBRACES posOrNegNumber tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING.tCOLON tLEFTBRACES tPHRASE tTO tPHRASE tRIGHTRANGE + searchBase: tSTRING.tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING.tCOLON tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTRANGE + + tCOLON shift 22 + . reduce 14 (src line 94) + + +state 13 + searchBase: tNUMBER. (15) + + . reduce 15 (src line 98) + + +state 14 + searchBase: tPHRASE. (16) + + . reduce 16 (src line 102) + + +state 15 + searchBase: tSLASH. (17) + + . reduce 17 (src line 108) + + +state 16 + searchLogicParts: searchLogicPart searchLogicParts. (2) + + . reduce 2 (src line 36) + + +state 17 + searchLogicPart: searchLogicSimplePart tOR.searchLogicPart + + tSTRING shift 12 + tPHRASE shift 14 + tNUMBER shift 13 + tSLASH shift 15 + tNOT shift 7 + tPLUS shift 10 + tMINUS shift 11 + tLEFTBRACKET shift 6 + . error + + searchBase goto 9 + searchPart goto 5 + searchLogicPart goto 23 + searchLogicSimplePart goto 4 + searchPrefix goto 8 + +state 18 + searchLogicPart: searchLogicSimplePart tAND.searchLogicPart + + tSTRING shift 12 + tPHRASE shift 14 + tNUMBER shift 13 + tSLASH shift 15 + tNOT shift 7 + tPLUS shift 10 + tMINUS shift 11 + tLEFTBRACKET shift 6 + . error + + searchBase goto 9 + searchPart goto 5 + searchLogicPart goto 24 + searchLogicSimplePart goto 4 + searchPrefix goto 8 + +state 19 + searchLogicSimplePart: tLEFTBRACKET searchLogicPart.tRIGHTBRACKET + + tRIGHTBRACKET shift 25 + . error + + +state 20 + searchLogicSimplePart: tNOT searchLogicSimplePart. (9) + + . reduce 9 (src line 66) + + +state 21 + searchPart: searchPrefix searchBase. (10) + + . reduce 10 (src line 71) + + +state 22 + searchBase: tSTRING tCOLON.tSTRING + searchBase: tSTRING tCOLON.tLEFTBRACKET tSTRING tRIGHTBRACKET + searchBase: tSTRING tCOLON.posOrNegNumber + searchBase: tSTRING tCOLON.tPHRASE + searchBase: tSTRING tCOLON.tSLASH + searchBase: tSTRING tCOLON.tGREATER posOrNegNumber + searchBase: tSTRING tCOLON.tGREATER tEQUAL posOrNegNumber + searchBase: tSTRING tCOLON.tLESS posOrNegNumber + searchBase: tSTRING tCOLON.tLESS tEQUAL posOrNegNumber + searchBase: tSTRING tCOLON.tGREATER tPHRASE + searchBase: tSTRING tCOLON.tGREATER tEQUAL tPHRASE + searchBase: tSTRING tCOLON.tLESS tPHRASE + searchBase: tSTRING tCOLON.tLESS tEQUAL tPHRASE + searchBase: tSTRING tCOLON.tLEFTRANGE tSTAR tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING tCOLON.tLEFTRANGE posOrNegNumber tTO tSTAR tRIGHTRANGE + searchBase: tSTRING tCOLON.tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTBRACES + searchBase: tSTRING tCOLON.tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTBRACES + searchBase: tSTRING tCOLON.tLEFTBRACES posOrNegNumber tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING tCOLON.tLEFTBRACES tPHRASE tTO tPHRASE tRIGHTRANGE + searchBase: tSTRING tCOLON.tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING tCOLON.tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTRANGE + + tSTRING shift 26 + tPHRASE shift 29 + tNUMBER shift 35 + tSLASH shift 30 + tMINUS shift 36 + tLEFTBRACKET shift 27 + tLEFTRANGE shift 33 + tLEFTBRACES shift 34 + tGREATER shift 31 + tLESS shift 32 + . error + + posOrNegNumber goto 28 + +state 23 + searchLogicPart: searchLogicSimplePart tOR searchLogicPart. (5) + + . reduce 5 (src line 49) + + +state 24 + searchLogicPart: searchLogicSimplePart tAND searchLogicPart. (6) + + . reduce 6 (src line 53) + + +state 25 + searchLogicSimplePart: tLEFTBRACKET searchLogicPart tRIGHTBRACKET. (8) + + . reduce 8 (src line 62) + + +state 26 + searchBase: tSTRING tCOLON tSTRING. (18) + + . reduce 18 (src line 114) + + +state 27 + searchBase: tSTRING tCOLON tLEFTBRACKET.tSTRING tRIGHTBRACKET + + tSTRING shift 37 + . error + + +state 28 + searchBase: tSTRING tCOLON posOrNegNumber. (20) + + . reduce 20 (src line 126) + + +state 29 + searchBase: tSTRING tCOLON tPHRASE. (21) + + . reduce 21 (src line 132) + + +state 30 + searchBase: tSTRING tCOLON tSLASH. (22) + + . reduce 22 (src line 138) + + +state 31 + searchBase: tSTRING tCOLON tGREATER.posOrNegNumber + searchBase: tSTRING tCOLON tGREATER.tEQUAL posOrNegNumber + searchBase: tSTRING tCOLON tGREATER.tPHRASE + searchBase: tSTRING tCOLON tGREATER.tEQUAL tPHRASE + + tPHRASE shift 40 + tNUMBER shift 35 + tMINUS shift 36 + tEQUAL shift 39 + . error + + posOrNegNumber goto 38 + +state 32 + searchBase: tSTRING tCOLON tLESS.posOrNegNumber + searchBase: tSTRING tCOLON tLESS.tEQUAL posOrNegNumber + searchBase: tSTRING tCOLON tLESS.tPHRASE + searchBase: tSTRING tCOLON tLESS.tEQUAL tPHRASE + + tPHRASE shift 43 + tNUMBER shift 35 + tMINUS shift 36 + tEQUAL shift 42 + . error + + posOrNegNumber goto 41 + +state 33 + searchBase: tSTRING tCOLON tLEFTRANGE.tSTAR tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING tCOLON tLEFTRANGE.posOrNegNumber tTO tSTAR tRIGHTRANGE + searchBase: tSTRING tCOLON tLEFTRANGE.posOrNegNumber tTO posOrNegNumber tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE.tPHRASE tTO tPHRASE tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE.posOrNegNumber tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING tCOLON tLEFTRANGE.tPHRASE tTO tPHRASE tRIGHTRANGE + + tPHRASE shift 46 + tNUMBER shift 35 + tSTAR shift 44 + tMINUS shift 36 + . error + + posOrNegNumber goto 45 + +state 34 + searchBase: tSTRING tCOLON tLEFTBRACES.posOrNegNumber tTO posOrNegNumber tRIGHTRANGE + searchBase: tSTRING tCOLON tLEFTBRACES.tPHRASE tTO tPHRASE tRIGHTRANGE + + tPHRASE shift 48 + tNUMBER shift 35 + tMINUS shift 36 + . error + + posOrNegNumber goto 47 + +state 35 + posOrNegNumber: tNUMBER. (39) + + . reduce 39 (src line 263) + + +state 36 + posOrNegNumber: tMINUS.tNUMBER + + tNUMBER shift 49 + . error + + +state 37 + searchBase: tSTRING tCOLON tLEFTBRACKET tSTRING.tRIGHTBRACKET + + tRIGHTBRACKET shift 50 + . error + + +state 38 + searchBase: tSTRING tCOLON tGREATER posOrNegNumber. (23) + + . reduce 23 (src line 144) + + +state 39 + searchBase: tSTRING tCOLON tGREATER tEQUAL.posOrNegNumber + searchBase: tSTRING tCOLON tGREATER tEQUAL.tPHRASE + + tPHRASE shift 52 + tNUMBER shift 35 + tMINUS shift 36 + . error + + posOrNegNumber goto 51 + +state 40 + searchBase: tSTRING tCOLON tGREATER tPHRASE. (27) + + . reduce 27 (src line 172) + + +state 41 + searchBase: tSTRING tCOLON tLESS posOrNegNumber. (25) + + . reduce 25 (src line 158) + + +state 42 + searchBase: tSTRING tCOLON tLESS tEQUAL.posOrNegNumber + searchBase: tSTRING tCOLON tLESS tEQUAL.tPHRASE + + tPHRASE shift 54 + tNUMBER shift 35 + tMINUS shift 36 + . error + + posOrNegNumber goto 53 + +state 43 + searchBase: tSTRING tCOLON tLESS tPHRASE. (29) + + . reduce 29 (src line 186) + + +state 44 + searchBase: tSTRING tCOLON tLEFTRANGE tSTAR.tTO posOrNegNumber tRIGHTRANGE + + tTO shift 55 + . error + + +state 45 + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber.tTO tSTAR tRIGHTRANGE + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber.tTO posOrNegNumber tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber.tTO posOrNegNumber tRIGHTRANGE + + tTO shift 56 + . error + + +state 46 + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE.tTO tPHRASE tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE.tTO tPHRASE tRIGHTRANGE + + tTO shift 57 + . error + + +state 47 + searchBase: tSTRING tCOLON tLEFTBRACES posOrNegNumber.tTO posOrNegNumber tRIGHTRANGE + + tTO shift 58 + . error + + +state 48 + searchBase: tSTRING tCOLON tLEFTBRACES tPHRASE.tTO tPHRASE tRIGHTRANGE + + tTO shift 59 + . error + + +state 49 + posOrNegNumber: tMINUS tNUMBER. (40) + + . reduce 40 (src line 267) + + +state 50 + searchBase: tSTRING tCOLON tLEFTBRACKET tSTRING tRIGHTBRACKET. (19) + + . reduce 19 (src line 120) + + +state 51 + searchBase: tSTRING tCOLON tGREATER tEQUAL posOrNegNumber. (24) + + . reduce 24 (src line 151) + + +state 52 + searchBase: tSTRING tCOLON tGREATER tEQUAL tPHRASE. (28) + + . reduce 28 (src line 179) + + +state 53 + searchBase: tSTRING tCOLON tLESS tEQUAL posOrNegNumber. (26) + + . reduce 26 (src line 165) + + +state 54 + searchBase: tSTRING tCOLON tLESS tEQUAL tPHRASE. (30) + + . reduce 30 (src line 193) + + +state 55 + searchBase: tSTRING tCOLON tLEFTRANGE tSTAR tTO.posOrNegNumber tRIGHTRANGE + + tNUMBER shift 35 + tMINUS shift 36 + . error + + posOrNegNumber goto 60 + +state 56 + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO.tSTAR tRIGHTRANGE + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO.posOrNegNumber tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO.posOrNegNumber tRIGHTRANGE + + tNUMBER shift 35 + tSTAR shift 61 + tMINUS shift 36 + . error + + posOrNegNumber goto 62 + +state 57 + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE tTO.tPHRASE tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE tTO.tPHRASE tRIGHTRANGE + + tPHRASE shift 63 + . error + + +state 58 + searchBase: tSTRING tCOLON tLEFTBRACES posOrNegNumber tTO.posOrNegNumber tRIGHTRANGE + + tNUMBER shift 35 + tMINUS shift 36 + . error + + posOrNegNumber goto 64 + +state 59 + searchBase: tSTRING tCOLON tLEFTBRACES tPHRASE tTO.tPHRASE tRIGHTRANGE + + tPHRASE shift 65 + . error + + +state 60 + searchBase: tSTRING tCOLON tLEFTRANGE tSTAR tTO posOrNegNumber.tRIGHTRANGE + + tRIGHTRANGE shift 66 + . error + + +state 61 + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO tSTAR.tRIGHTRANGE + + tRIGHTRANGE shift 67 + . error + + +state 62 + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber.tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber.tRIGHTRANGE + + tRIGHTRANGE shift 69 + tRIGHTBRACES shift 68 + . error + + +state 63 + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE tTO tPHRASE.tRIGHTBRACES + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE tTO tPHRASE.tRIGHTRANGE + + tRIGHTRANGE shift 71 + tRIGHTBRACES shift 70 + . error + + +state 64 + searchBase: tSTRING tCOLON tLEFTBRACES posOrNegNumber tTO posOrNegNumber.tRIGHTRANGE + + tRIGHTRANGE shift 72 + . error + + +state 65 + searchBase: tSTRING tCOLON tLEFTBRACES tPHRASE tTO tPHRASE.tRIGHTRANGE + + tRIGHTRANGE shift 73 + . error + + +state 66 + searchBase: tSTRING tCOLON tLEFTRANGE tSTAR tTO posOrNegNumber tRIGHTRANGE. (31) + + . reduce 31 (src line 200) + + +state 67 + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO tSTAR tRIGHTRANGE. (32) + + . reduce 32 (src line 207) + + +state 68 + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTBRACES. (33) + + . reduce 33 (src line 214) + + +state 69 + searchBase: tSTRING tCOLON tLEFTRANGE posOrNegNumber tTO posOrNegNumber tRIGHTRANGE. (37) + + . reduce 37 (src line 246) + + +state 70 + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTBRACES. (34) + + . reduce 34 (src line 222) + + +state 71 + searchBase: tSTRING tCOLON tLEFTRANGE tPHRASE tTO tPHRASE tRIGHTRANGE. (38) + + . reduce 38 (src line 254) + + +state 72 + searchBase: tSTRING tCOLON tLEFTBRACES posOrNegNumber tTO posOrNegNumber tRIGHTRANGE. (35) + + . reduce 35 (src line 230) + + +state 73 + searchBase: tSTRING tCOLON tLEFTBRACES tPHRASE tTO tPHRASE tRIGHTRANGE. (36) + + . reduce 36 (src line 238) + + +24 terminals, 9 nonterminals +41 grammar rules, 74/16000 states +0 shift/reduce, 0 reduce/reduce conflicts reported +58 working sets used +memory: parser 42/240000 +12 extra closures +112 shift entries, 1 exceptions +23 goto entries +20 entries saved by goto default +Optimizer space used: output 93/240000 +93 table entries, 0 zero +maximum spread: 24, maximum offset: 58 diff --git a/pkg/unify-query/log/hook.go b/pkg/unify-query/log/hook.go index c89a2ae9b..cbcc05f46 100644 --- a/pkg/unify-query/log/hook.go +++ b/pkg/unify-query/log/hook.go @@ -113,6 +113,6 @@ func init() { // InitTestLogger 加载单元测试日志配置 func InitTestLogger() { // 加载配置 - viper.Set(LevelConfigPath, "warn") + viper.Set(LevelConfigPath, "debug") initLogConfig() } diff --git a/pkg/unify-query/tsdb/elasticsearch/instance.go b/pkg/unify-query/tsdb/elasticsearch/instance.go index a0a94ad28..80b28b4a2 100644 --- a/pkg/unify-query/tsdb/elasticsearch/instance.go +++ b/pkg/unify-query/tsdb/elasticsearch/instance.go @@ -233,7 +233,7 @@ func (i *Instance) esQuery(ctx context.Context, qo *queryOption, fact *FormatFac // querystring 生成 elastic.query if qb.QueryString != "" { qs := NewQueryString(qb.QueryString, fact.NestedField) - q, qsErr := qs.Parser() + q, qsErr := qs.ToDSL() if qsErr != nil { return nil, qsErr } diff --git a/pkg/unify-query/tsdb/elasticsearch/query_string.go b/pkg/unify-query/tsdb/elasticsearch/query_string.go index df9d4abfe..e9ba5f390 100644 --- a/pkg/unify-query/tsdb/elasticsearch/query_string.go +++ b/pkg/unify-query/tsdb/elasticsearch/query_string.go @@ -12,8 +12,9 @@ package elasticsearch import ( "fmt" - parser "github.com/bytedance/go-querystring-parser" elastic "github.com/olivere/elastic/v7" + + qs "github.com/TencentBlueKing/bkmonitor-datalink/pkg/unify-query/internal/querystring" ) type QueryString struct { @@ -43,27 +44,26 @@ func (s *QueryString) queryString(str string) elastic.Query { return elastic.NewQueryStringQuery(str).AnalyzeWildcard(true) } -func (s *QueryString) Parser() (elastic.Query, error) { +func (s *QueryString) ToDSL() (elastic.Query, error) { if s.q == "" || s.q == "*" { return nil, nil } // 解析失败,或者没有 nested 字段,则使用透传的方式查询 - qs := s.queryString(s.q) - - ast, err := parser.Parse(s.q) + q := s.queryString(s.q) + ast, err := qs.Parse(s.q) if err != nil { - return qs, nil + return q, nil } conditionQuery, err := s.walk(ast) if err != nil { - return qs, nil + return q, nil } // 如果 nestedFields 不存在则直接使用 queryString 透传 if len(s.nestedFields) == 0 { - return qs, nil + return q, nil } for nestedKey := range s.nestedFields { @@ -81,20 +81,20 @@ func (s *QueryString) check(field string) { } } -func (s *QueryString) walk(condition parser.Condition) (elastic.Query, error) { +func (s *QueryString) walk(expr qs.Expr) (elastic.Query, error) { var ( leftQ elastic.Query rightQ elastic.Query err error ) - switch c := condition.(type) { - case *parser.NotCondition: - leftQ, err = s.walk(c.Condition) + switch c := expr.(type) { + case *qs.NotExpr: + leftQ, err = s.walk(c.Expr) if err != nil { return nil, err } leftQ = elastic.NewBoolQuery().MustNot(leftQ) - case *parser.OrCondition: + case *qs.OrExpr: leftQ, err = s.walk(c.Left) if err != nil { return nil, err @@ -104,7 +104,7 @@ func (s *QueryString) walk(condition parser.Condition) (elastic.Query, error) { return nil, err } leftQ = elastic.NewBoolQuery().Should(leftQ, rightQ) - case *parser.AndCondition: + case *qs.AndExpr: leftQ, err = s.walk(c.Left) if err != nil { return nil, err @@ -114,14 +114,14 @@ func (s *QueryString) walk(condition parser.Condition) (elastic.Query, error) { return nil, err } leftQ = elastic.NewBoolQuery().Must(leftQ, rightQ) - case *parser.MatchCondition: + case *qs.MatchExpr: if c.Field != "" { leftQ = elastic.NewMatchPhraseQuery(c.Field, c.Value) s.check(c.Field) } else { leftQ = s.queryString(fmt.Sprintf(`"%s"`, c.Value)) } - case *parser.NumberRangeCondition: + case *qs.NumberRangeExpr: q := elastic.NewRangeQuery(c.Field) if c.IncludeStart { q.Gte(*c.Start) @@ -135,7 +135,7 @@ func (s *QueryString) walk(condition parser.Condition) (elastic.Query, error) { } s.check(c.Field) leftQ = q - case *parser.WildcardCondition: + case *qs.WildcardExpr: if c.Field != "" { leftQ = elastic.NewWildcardQuery(c.Field, c.Value) s.check(c.Field) @@ -143,7 +143,7 @@ func (s *QueryString) walk(condition parser.Condition) (elastic.Query, error) { leftQ = s.queryString(c.Value) } default: - err = fmt.Errorf("condition type is not match %T", condition) + err = fmt.Errorf("expr type is not match %T", expr) } return leftQ, err } diff --git a/pkg/unify-query/tsdb/elasticsearch/query_string_test.go b/pkg/unify-query/tsdb/elasticsearch/query_string_test.go index 9b28e3266..3f8e50f6b 100644 --- a/pkg/unify-query/tsdb/elasticsearch/query_string_test.go +++ b/pkg/unify-query/tsdb/elasticsearch/query_string_test.go @@ -33,18 +33,17 @@ func TestQsToDsl(t *testing.T) { { q: `log: "ERROR MSG"`, expected: `{"query_string":{"analyze_wildcard":true,"query":"log: \"ERROR MSG\""}}`, + //expected: `{"match_phrase":{"log":{"query":"ERROR MSG"}}}`, }, { q: `quick brown fox`, expected: `{"query_string":{"analyze_wildcard":true,"query":"quick brown fox"}}`, + //expected: `{"bool":{"must":[{"query_string":{"analyze_wildcard":true,"query":"\"quick\""}},{"bool":{"must":[{"query_string":{"analyze_wildcard":true,"query":"\"brown\""}},{"query_string":{"analyze_wildcard":true,"query":"\"fox\""}}]}}]}}`, }, { q: `word.key: qu?ck`, expected: `{"query_string":{"analyze_wildcard":true,"query":"word.key: qu?ck"}}`, - }, - { - q: "\"message queue conflict\"", - expected: `{"query_string":{"analyze_wildcard":true,"query":"\"message queue conflict\""}}`, + //expected: `{"wildcard":{"word.key":{"value":"qu?ck"}}}`, }, { q: "\"message queue conflict\"", @@ -57,6 +56,7 @@ func TestQsToDsl(t *testing.T) { { q: `sync_spaces AND -keyword AND -BKLOGAPI`, expected: `{"query_string":{"analyze_wildcard":true,"query":"sync_spaces AND -keyword AND -BKLOGAPI"}}`, + //expected: `{"bool":{"must":[{"query_string":{"analyze_wildcard":true,"query":"\"sync_spaces\""}},{"bool":{"must":[{"bool":{"must_not":{"query_string":{"analyze_wildcard":true,"query":"\"keyword\""}}}},{"bool":{"must_not":{"query_string":{"analyze_wildcard":true,"query":"\"BKLOGAPI\""}}}}]}}]}}`, }, { q: `*`, @@ -73,7 +73,7 @@ func TestQsToDsl(t *testing.T) { } return "" }) - query, err := qs.Parser() + query, err := qs.ToDSL() if err == nil { if query != nil { body, _ := query.Source()