mirror of https://github.com/milvus-io/milvus.git
Support antlr as plan parser (#16696)
Signed-off-by: dragondriver <jiquan.long@zilliz.com> Co-authored-by: xaxys <tpnnghd@163.com> Co-authored-by: xaxys <tpnnghd@163.com>pull/16814/head
parent
b0053b7a45
commit
98ceb162aa
1
go.mod
1
go.mod
|
@ -7,6 +7,7 @@ require (
|
|||
github.com/HdrHistogram/hdrhistogram-go v1.0.1 // indirect
|
||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||
github.com/antonmedv/expr v1.8.9
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e // indirect
|
||||
github.com/apache/arrow/go/v8 v8.0.0-20220322092137-778b1772fd20
|
||||
github.com/apache/pulsar-client-go v0.6.1-0.20210728062540-29414db801a7
|
||||
github.com/apache/pulsar-client-go/oauth2 v0.0.0-20201120111947-b8bd55bc02bd // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -72,6 +72,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5
|
|||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e h1:GCzyKMDDjSGnlpl3clrdAK7I1AaVoaiKDOYkUzChZzg=
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
|
||||
github.com/antonmedv/expr v1.8.9 h1:O9stiHmHHww9b4ozhPx7T6BK7fXfOCHJ8ybxf0833zw=
|
||||
github.com/antonmedv/expr v1.8.9/go.mod h1:5qsM3oLGDND7sDmQGDXHkYfkjYMUX14qsgqmHhwGEk8=
|
||||
github.com/apache/arrow/go/v8 v8.0.0-20220322092137-778b1772fd20 h1:YcSFhAin12rxRsvvfzD6gepH7jZwtFVdikXRyhzUC2w=
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,131 @@
|
|||
grammar Plan;
|
||||
|
||||
expr:
|
||||
IntegerConstant # Integer
|
||||
| FloatingConstant # Floating
|
||||
| BooleanConstant # Boolean
|
||||
| StringLiteral # String
|
||||
| Identifier # Identifier
|
||||
| '(' expr ')' # Parens
|
||||
| expr LIKE StringLiteral # Like
|
||||
| expr POW expr # Power
|
||||
| op = (ADD | SUB | BNOT | NOT) expr # Unary
|
||||
// | '(' typeName ')' expr # Cast
|
||||
| expr op = (MUL | DIV | MOD) expr # MulDivMod
|
||||
| expr op = (ADD | SUB) expr # AddSub
|
||||
| expr op = (SHL | SHR) expr # Shift
|
||||
| expr op = (IN | NIN) ('[' expr (',' expr)* ','? ']') # Term
|
||||
| expr op = (IN | NIN) EmptyTerm # EmptyTerm
|
||||
| expr op1 = (LT | LE) expr op2 = (LT | LE) expr # Range
|
||||
| expr op1 = (GT | GE) expr op2 = (GT | GE) expr # ReverseRange
|
||||
| expr op = (LT | LE | GT | GE) expr # Relational
|
||||
| expr op = (EQ | NE) expr # Equality
|
||||
| expr BAND expr # BitAnd
|
||||
| expr BXOR expr # BitXor
|
||||
| expr BOR expr # BitOr
|
||||
| expr AND expr # LogicalAnd
|
||||
| expr OR expr # LogicalOr;
|
||||
|
||||
// typeName: ty = (BOOL | INT8 | INT16 | INT32 | INT64 | FLOAT | DOUBLE);
|
||||
|
||||
// BOOL: 'bool';
|
||||
// INT8: 'int8';
|
||||
// INT16: 'int16';
|
||||
// INT32: 'int32';
|
||||
// INT64: 'int64';
|
||||
// FLOAT: 'float';
|
||||
// DOUBLE: 'double';
|
||||
|
||||
LT: '<';
|
||||
LE: '<=';
|
||||
GT: '>';
|
||||
GE: '>=';
|
||||
EQ: '==';
|
||||
NE: '!=';
|
||||
|
||||
LIKE: 'like' | 'LIKE';
|
||||
|
||||
ADD: '+';
|
||||
SUB: '-';
|
||||
MUL: '*';
|
||||
DIV: '/';
|
||||
MOD: '%';
|
||||
POW: '**';
|
||||
SHL: '<<';
|
||||
SHR: '>>';
|
||||
BAND: '&';
|
||||
BOR: '|';
|
||||
BXOR: '^';
|
||||
|
||||
AND: '&&' | 'and';
|
||||
OR: '||' | 'or';
|
||||
|
||||
BNOT: '~';
|
||||
NOT: '!' | 'not';
|
||||
|
||||
IN: 'in';
|
||||
NIN: 'not in';
|
||||
EmptyTerm: '[' (Whitespace | Newline)* ']';
|
||||
|
||||
BooleanConstant: 'true' | 'True' | 'TRUE' | 'false' | 'False' | 'FALSE';
|
||||
|
||||
IntegerConstant:
|
||||
DecimalConstant
|
||||
| OctalConstant
|
||||
| HexadecimalConstant
|
||||
| BinaryConstant;
|
||||
|
||||
FloatingConstant:
|
||||
DecimalFloatingConstant
|
||||
| HexadecimalFloatingConstant;
|
||||
|
||||
Identifier: Nondigit (Nondigit | Digit)*;
|
||||
|
||||
StringLiteral: EncodingPrefix? '"' SCharSequence? '"';
|
||||
|
||||
fragment EncodingPrefix: 'u8' | 'u' | 'U' | 'L';
|
||||
|
||||
fragment SCharSequence: SChar+;
|
||||
|
||||
fragment SChar: ~["\\\r\n] | EscapeSequence | '\\\n' | '\\\r\n';
|
||||
fragment Nondigit: [a-zA-Z_];
|
||||
fragment Digit: [0-9];
|
||||
fragment BinaryConstant: '0' [bB] [0-1]+;
|
||||
fragment DecimalConstant: NonzeroDigit Digit*;
|
||||
fragment OctalConstant: '0' OctalDigit*;
|
||||
fragment HexadecimalConstant: '0' [xX] HexadecimalDigitSequence;
|
||||
fragment NonzeroDigit: [1-9];
|
||||
fragment OctalDigit: [0-7];
|
||||
fragment HexadecimalDigit: [0-9a-fA-F];
|
||||
fragment HexQuad:
|
||||
HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit;
|
||||
fragment UniversalCharacterName:
|
||||
'\\u' HexQuad
|
||||
| '\\U' HexQuad HexQuad;
|
||||
fragment DecimalFloatingConstant:
|
||||
FractionalConstant ExponentPart?
|
||||
| DigitSequence ExponentPart;
|
||||
fragment HexadecimalFloatingConstant:
|
||||
'0' [xX] (
|
||||
HexadecimalFractionalConstant
|
||||
| HexadecimalDigitSequence
|
||||
) BinaryExponentPart;
|
||||
fragment FractionalConstant:
|
||||
DigitSequence? '.' DigitSequence
|
||||
| DigitSequence '.';
|
||||
fragment ExponentPart: [eE] [+-]? DigitSequence;
|
||||
fragment DigitSequence: Digit+;
|
||||
fragment HexadecimalFractionalConstant:
|
||||
HexadecimalDigitSequence? '.' HexadecimalDigitSequence
|
||||
| HexadecimalDigitSequence '.';
|
||||
fragment HexadecimalDigitSequence: HexadecimalDigit+;
|
||||
fragment BinaryExponentPart: [pP] [+-]? DigitSequence;
|
||||
fragment EscapeSequence:
|
||||
'\\' ['"?abfnrtv\\]
|
||||
| '\\' OctalDigit OctalDigit? OctalDigit?
|
||||
| '\\x' HexadecimalDigitSequence
|
||||
| UniversalCharacterName;
|
||||
|
||||
Whitespace: [ \t]+ -> skip;
|
||||
|
||||
Newline: ( '\r' '\n'? | '\n') -> skip;
|
|
@ -0,0 +1,23 @@
|
|||
# Generate Parser with Antlr4
|
||||
|
||||
## Install Antlr4
|
||||
|
||||
Please follow [install antlr4](https://github.com/antlr/antlr4/blob/master/doc/go-target.md) to install the antlr tool.
|
||||
|
||||
The version of antlr tool: `4.9`.
|
||||
|
||||
## Code Generate
|
||||
|
||||
After you install the antlr4, you can generate the parser code in golang with:
|
||||
|
||||
```shell
|
||||
export CLASSPATH=".:${PWD}/antlr-4.9-complete.jar:$CLASSPATH"
|
||||
alias antlr4='java -Xmx500M -cp "${PWD}/antlr-4.9-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
|
||||
alias grun='java -Xmx500M -cp "${PWD}/antlr-4.9-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'
|
||||
```
|
||||
|
||||
```shell
|
||||
antlr4 -Dlanguage=Go -package planparserv2 -o generated -no-listener -visitor Plan.g4
|
||||
```
|
||||
|
||||
All generated code will be under directory `generated`.
|
|
@ -0,0 +1,15 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
)
|
||||
|
||||
// CheckIdentical check if two exprs are identical.
|
||||
func CheckIdentical(expr, other *planpb.Expr) bool {
|
||||
v := NewShowExprVisitor()
|
||||
js1 := v.VisitExpr(expr)
|
||||
js2 := v.VisitExpr(other)
|
||||
return reflect.DeepEqual(js1, js2)
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCheckIdentical(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStr1 := `not (((Int64Field > 0) and (FloatField <= 20.0)) or ((Int32Field in [1, 2, 3]) and (VarCharField < "str")))`
|
||||
exprStr2 := `Int32Field in [1, 2, 3]`
|
||||
|
||||
expr1, err := ParseExpr(helper, exprStr1)
|
||||
assert.NoError(t, err)
|
||||
expr2, err := ParseExpr(helper, exprStr2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.True(t, CheckIdentical(expr1, expr1))
|
||||
assert.True(t, CheckIdentical(expr2, expr2))
|
||||
assert.False(t, CheckIdentical(expr1, expr2))
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
)
|
||||
|
||||
type errorListener struct {
|
||||
*antlr.DefaultErrorListener
|
||||
err error
|
||||
}
|
||||
|
||||
func (l *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
|
||||
l.err = fmt.Errorf("line " + strconv.Itoa(line) + ":" + strconv.Itoa(column) + " " + msg)
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package planparserv2
|
||||
|
||||
const float64EqualityThreshold = 1e-9
|
||||
|
||||
func floatingEqual(a, b float64) bool {
|
||||
// return math.Abs(a-b) <= float64EqualityThreshold
|
||||
return a == b
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package planparserv2
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test_floatingEqual(t *testing.T) {
|
||||
type args struct {
|
||||
a float64
|
||||
b float64
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
args: args{
|
||||
a: 1.0,
|
||||
b: 1.0,
|
||||
},
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
args: args{
|
||||
a: 1.0,
|
||||
b: 2.0,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
args: args{
|
||||
a: 0.000000001,
|
||||
b: 0,
|
||||
},
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := floatingEqual(tt.args.a, tt.args.b); got != tt.want {
|
||||
t.Errorf("floatingEqual() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
token literal names:
|
||||
null
|
||||
'('
|
||||
')'
|
||||
'['
|
||||
','
|
||||
']'
|
||||
'<'
|
||||
'<='
|
||||
'>'
|
||||
'>='
|
||||
'=='
|
||||
'!='
|
||||
null
|
||||
'+'
|
||||
'-'
|
||||
'*'
|
||||
'/'
|
||||
'%'
|
||||
'**'
|
||||
'<<'
|
||||
'>>'
|
||||
'&'
|
||||
'|'
|
||||
'^'
|
||||
null
|
||||
null
|
||||
'~'
|
||||
null
|
||||
'in'
|
||||
'not in'
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
|
||||
token symbolic names:
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
null
|
||||
LT
|
||||
LE
|
||||
GT
|
||||
GE
|
||||
EQ
|
||||
NE
|
||||
LIKE
|
||||
ADD
|
||||
SUB
|
||||
MUL
|
||||
DIV
|
||||
MOD
|
||||
POW
|
||||
SHL
|
||||
SHR
|
||||
BAND
|
||||
BOR
|
||||
BXOR
|
||||
AND
|
||||
OR
|
||||
BNOT
|
||||
NOT
|
||||
IN
|
||||
NIN
|
||||
EmptyTerm
|
||||
BooleanConstant
|
||||
IntegerConstant
|
||||
FloatingConstant
|
||||
Identifier
|
||||
StringLiteral
|
||||
Whitespace
|
||||
Newline
|
||||
|
||||
rule names:
|
||||
expr
|
||||
|
||||
|
||||
atn:
|
||||
[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 39, 91, 4, 2, 9, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 5, 2, 17, 10, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 7, 2, 73, 10, 2, 12, 2, 14, 2, 76, 11, 2, 3, 2, 5, 2, 79, 10, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 7, 2, 86, 10, 2, 12, 2, 14, 2, 89, 11, 2, 3, 2, 2, 3, 2, 3, 2, 2, 11, 4, 2, 15, 16, 28, 29, 3, 2, 17, 19, 3, 2, 15, 16, 3, 2, 21, 22, 3, 2, 8, 9, 3, 2, 10, 11, 3, 2, 8, 11, 3, 2, 12, 13, 3, 2, 30, 31, 2, 113, 2, 16, 3, 2, 2, 2, 4, 5, 8, 2, 1, 2, 5, 17, 7, 34, 2, 2, 6, 17, 7, 35, 2, 2, 7, 17, 7, 33, 2, 2, 8, 17, 7, 37, 2, 2, 9, 17, 7, 36, 2, 2, 10, 11, 7, 3, 2, 2, 11, 12, 5, 2, 2, 2, 12, 13, 7, 4, 2, 2, 13, 17, 3, 2, 2, 2, 14, 15, 9, 2, 2, 2, 15, 17, 5, 2, 2, 17, 16, 4, 3, 2, 2, 2, 16, 6, 3, 2, 2, 2, 16, 7, 3, 2, 2, 2, 16, 8, 3, 2, 2, 2, 16, 9, 3, 2, 2, 2, 16, 10, 3, 2, 2, 2, 16, 14, 3, 2, 2, 2, 17, 87, 3, 2, 2, 2, 18, 19, 12, 18, 2, 2, 19, 20, 7, 20, 2, 2, 20, 86, 5, 2, 2, 19, 21, 22, 12, 16, 2, 2, 22, 23, 9, 3, 2, 2, 23, 86, 5, 2, 2, 17, 24, 25, 12, 15, 2, 2, 25, 26, 9, 4, 2, 2, 26, 86, 5, 2, 2, 16, 27, 28, 12, 14, 2, 2, 28, 29, 9, 5, 2, 2, 29, 86, 5, 2, 2, 15, 30, 31, 12, 11, 2, 2, 31, 32, 9, 6, 2, 2, 32, 33, 5, 2, 2, 2, 33, 34, 9, 6, 2, 2, 34, 35, 5, 2, 2, 12, 35, 86, 3, 2, 2, 2, 36, 37, 12, 10, 2, 2, 37, 38, 9, 7, 2, 2, 38, 39, 5, 2, 2, 2, 39, 40, 9, 7, 2, 2, 40, 41, 5, 2, 2, 11, 41, 86, 3, 2, 2, 2, 42, 43, 12, 9, 2, 2, 43, 44, 9, 8, 2, 2, 44, 86, 5, 2, 2, 10, 45, 46, 12, 8, 2, 2, 46, 47, 9, 9, 2, 2, 47, 86, 5, 2, 2, 9, 48, 49, 12, 7, 2, 2, 49, 50, 7, 23, 2, 2, 50, 86, 5, 2, 2, 8, 51, 52, 12, 6, 2, 2, 52, 53, 7, 25, 2, 2, 53, 86, 5, 2, 2, 7, 54, 55, 12, 5, 2, 2, 55, 56, 7, 24, 2, 2, 56, 86, 5, 2, 2, 6, 57, 58, 12, 4, 2, 2, 58, 59, 7, 26, 2, 2, 59, 86, 5, 2, 2, 5, 60, 61, 12, 3, 2, 2, 61, 62, 7, 27, 2, 2, 62, 86, 5, 2, 2, 4, 63, 64, 12, 19, 2, 2, 64, 65, 7, 14, 2, 2, 65, 86, 7, 37, 2, 2, 66, 67, 12, 13, 2, 2, 67, 68, 9, 10, 2, 2, 68, 69, 7, 5, 2, 2, 69, 74, 5, 2, 2, 2, 70, 71, 7, 6, 2, 2, 71, 73, 5, 2, 2, 2, 72, 70, 3, 2, 2, 2, 73, 76, 3, 2, 2, 2, 74, 72, 3, 2, 2, 2, 74, 75, 3, 2, 2, 2, 75, 78, 3, 2, 2, 2, 76, 74, 3, 2, 2, 2, 77, 79, 7, 6, 2, 2, 78, 77, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 80, 3, 2, 2, 2, 80, 81, 7, 7, 2, 2, 81, 86, 3, 2, 2, 2, 82, 83, 12, 12, 2, 2, 83, 84, 9, 10, 2, 2, 84, 86, 7, 32, 2, 2, 85, 18, 3, 2, 2, 2, 85, 21, 3, 2, 2, 2, 85, 24, 3, 2, 2, 2, 85, 27, 3, 2, 2, 2, 85, 30, 3, 2, 2, 2, 85, 36, 3, 2, 2, 2, 85, 42, 3, 2, 2, 2, 85, 45, 3, 2, 2, 2, 85, 48, 3, 2, 2, 2, 85, 51, 3, 2, 2, 2, 85, 54, 3, 2, 2, 2, 85, 57, 3, 2, 2, 2, 85, 60, 3, 2, 2, 2, 85, 63, 3, 2, 2, 2, 85, 66, 3, 2, 2, 2, 85, 82, 3, 2, 2, 2, 86, 89, 3, 2, 2, 2, 87, 85, 3, 2, 2, 2, 87, 88, 3, 2, 2, 2, 88, 3, 3, 2, 2, 2, 89, 87, 3, 2, 2, 2, 7, 16, 74, 78, 85, 87]
|
|
@ -0,0 +1,62 @@
|
|||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
LT=6
|
||||
LE=7
|
||||
GT=8
|
||||
GE=9
|
||||
EQ=10
|
||||
NE=11
|
||||
LIKE=12
|
||||
ADD=13
|
||||
SUB=14
|
||||
MUL=15
|
||||
DIV=16
|
||||
MOD=17
|
||||
POW=18
|
||||
SHL=19
|
||||
SHR=20
|
||||
BAND=21
|
||||
BOR=22
|
||||
BXOR=23
|
||||
AND=24
|
||||
OR=25
|
||||
BNOT=26
|
||||
NOT=27
|
||||
IN=28
|
||||
NIN=29
|
||||
EmptyTerm=30
|
||||
BooleanConstant=31
|
||||
IntegerConstant=32
|
||||
FloatingConstant=33
|
||||
Identifier=34
|
||||
StringLiteral=35
|
||||
Whitespace=36
|
||||
Newline=37
|
||||
'('=1
|
||||
')'=2
|
||||
'['=3
|
||||
','=4
|
||||
']'=5
|
||||
'<'=6
|
||||
'<='=7
|
||||
'>'=8
|
||||
'>='=9
|
||||
'=='=10
|
||||
'!='=11
|
||||
'+'=13
|
||||
'-'=14
|
||||
'*'=15
|
||||
'/'=16
|
||||
'%'=17
|
||||
'**'=18
|
||||
'<<'=19
|
||||
'>>'=20
|
||||
'&'=21
|
||||
'|'=22
|
||||
'^'=23
|
||||
'~'=26
|
||||
'in'=28
|
||||
'not in'=29
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,62 @@
|
|||
T__0=1
|
||||
T__1=2
|
||||
T__2=3
|
||||
T__3=4
|
||||
T__4=5
|
||||
LT=6
|
||||
LE=7
|
||||
GT=8
|
||||
GE=9
|
||||
EQ=10
|
||||
NE=11
|
||||
LIKE=12
|
||||
ADD=13
|
||||
SUB=14
|
||||
MUL=15
|
||||
DIV=16
|
||||
MOD=17
|
||||
POW=18
|
||||
SHL=19
|
||||
SHR=20
|
||||
BAND=21
|
||||
BOR=22
|
||||
BXOR=23
|
||||
AND=24
|
||||
OR=25
|
||||
BNOT=26
|
||||
NOT=27
|
||||
IN=28
|
||||
NIN=29
|
||||
EmptyTerm=30
|
||||
BooleanConstant=31
|
||||
IntegerConstant=32
|
||||
FloatingConstant=33
|
||||
Identifier=34
|
||||
StringLiteral=35
|
||||
Whitespace=36
|
||||
Newline=37
|
||||
'('=1
|
||||
')'=2
|
||||
'['=3
|
||||
','=4
|
||||
']'=5
|
||||
'<'=6
|
||||
'<='=7
|
||||
'>'=8
|
||||
'>='=9
|
||||
'=='=10
|
||||
'!='=11
|
||||
'+'=13
|
||||
'-'=14
|
||||
'*'=15
|
||||
'/'=16
|
||||
'%'=17
|
||||
'**'=18
|
||||
'<<'=19
|
||||
'>>'=20
|
||||
'&'=21
|
||||
'|'=22
|
||||
'^'=23
|
||||
'~'=26
|
||||
'in'=28
|
||||
'not in'=29
|
|
@ -0,0 +1,100 @@
|
|||
// Code generated from Plan.g4 by ANTLR 4.9. DO NOT EDIT.
|
||||
|
||||
package planparserv2 // Plan
|
||||
import "github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
type BasePlanVisitor struct {
|
||||
*antlr.BaseParseTreeVisitor
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitShift(ctx *ShiftContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitReverseRange(ctx *ReverseRangeContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitBitOr(ctx *BitOrContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitAddSub(ctx *AddSubContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitParens(ctx *ParensContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitRelational(ctx *RelationalContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitString(ctx *StringContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitTerm(ctx *TermContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitFloating(ctx *FloatingContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitRange(ctx *RangeContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitUnary(ctx *UnaryContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitLogicalOr(ctx *LogicalOrContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitInteger(ctx *IntegerContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitMulDivMod(ctx *MulDivModContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitIdentifier(ctx *IdentifierContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitBitXor(ctx *BitXorContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitLike(ctx *LikeContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitBitAnd(ctx *BitAndContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitLogicalAnd(ctx *LogicalAndContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitEmptyTerm(ctx *EmptyTermContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitEquality(ctx *EqualityContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitBoolean(ctx *BooleanContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
||||
|
||||
func (v *BasePlanVisitor) VisitPower(ctx *PowerContext) interface{} {
|
||||
return v.VisitChildren(ctx)
|
||||
}
|
|
@ -0,0 +1,333 @@
|
|||
// Code generated from Plan.g4 by ANTLR 4.9. DO NOT EDIT.
|
||||
|
||||
package planparserv2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"unicode"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
)
|
||||
|
||||
// Suppress unused import error
|
||||
var _ = fmt.Printf
|
||||
var _ = unicode.IsLetter
|
||||
|
||||
var serializedLexerAtn = []uint16{
|
||||
3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 39, 444,
|
||||
8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7,
|
||||
9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12,
|
||||
4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4,
|
||||
18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23,
|
||||
9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9,
|
||||
28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33,
|
||||
4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4,
|
||||
39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 4, 44,
|
||||
9, 44, 4, 45, 9, 45, 4, 46, 9, 46, 4, 47, 9, 47, 4, 48, 9, 48, 4, 49, 9,
|
||||
49, 4, 50, 9, 50, 4, 51, 9, 51, 4, 52, 9, 52, 4, 53, 9, 53, 4, 54, 9, 54,
|
||||
4, 55, 9, 55, 4, 56, 9, 56, 4, 57, 9, 57, 4, 58, 9, 58, 4, 59, 9, 59, 4,
|
||||
60, 9, 60, 4, 61, 9, 61, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5,
|
||||
3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3,
|
||||
10, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13,
|
||||
3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 158, 10, 13, 3, 14, 3, 14, 3, 15, 3,
|
||||
15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 20,
|
||||
3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 23, 3, 23, 3, 24, 3,
|
||||
24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 5, 25, 190, 10, 25, 3, 26, 3, 26,
|
||||
3, 26, 3, 26, 5, 26, 196, 10, 26, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3,
|
||||
28, 5, 28, 204, 10, 28, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 30,
|
||||
3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 31, 7, 31, 219, 10, 31, 12, 31, 14,
|
||||
31, 222, 11, 31, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32,
|
||||
3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3,
|
||||
32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32,
|
||||
5, 32, 253, 10, 32, 3, 33, 3, 33, 3, 33, 3, 33, 5, 33, 259, 10, 33, 3,
|
||||
34, 3, 34, 5, 34, 263, 10, 34, 3, 35, 3, 35, 3, 35, 7, 35, 268, 10, 35,
|
||||
12, 35, 14, 35, 271, 11, 35, 3, 36, 5, 36, 274, 10, 36, 3, 36, 3, 36, 5,
|
||||
36, 278, 10, 36, 3, 36, 3, 36, 3, 37, 3, 37, 3, 37, 5, 37, 285, 10, 37,
|
||||
3, 38, 6, 38, 288, 10, 38, 13, 38, 14, 38, 289, 3, 39, 3, 39, 3, 39, 3,
|
||||
39, 3, 39, 3, 39, 3, 39, 5, 39, 299, 10, 39, 3, 40, 3, 40, 3, 41, 3, 41,
|
||||
3, 42, 3, 42, 3, 42, 6, 42, 308, 10, 42, 13, 42, 14, 42, 309, 3, 43, 3,
|
||||
43, 7, 43, 314, 10, 43, 12, 43, 14, 43, 317, 11, 43, 3, 44, 3, 44, 7, 44,
|
||||
321, 10, 44, 12, 44, 14, 44, 324, 11, 44, 3, 45, 3, 45, 3, 45, 3, 45, 3,
|
||||
46, 3, 46, 3, 47, 3, 47, 3, 48, 3, 48, 3, 49, 3, 49, 3, 49, 3, 49, 3, 49,
|
||||
3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 3, 50, 5,
|
||||
50, 351, 10, 50, 3, 51, 3, 51, 5, 51, 355, 10, 51, 3, 51, 3, 51, 3, 51,
|
||||
5, 51, 360, 10, 51, 3, 52, 3, 52, 3, 52, 3, 52, 5, 52, 366, 10, 52, 3,
|
||||
52, 3, 52, 3, 53, 5, 53, 371, 10, 53, 3, 53, 3, 53, 3, 53, 3, 53, 3, 53,
|
||||
5, 53, 378, 10, 53, 3, 54, 3, 54, 5, 54, 382, 10, 54, 3, 54, 3, 54, 3,
|
||||
55, 6, 55, 387, 10, 55, 13, 55, 14, 55, 388, 3, 56, 5, 56, 392, 10, 56,
|
||||
3, 56, 3, 56, 3, 56, 3, 56, 3, 56, 5, 56, 399, 10, 56, 3, 57, 6, 57, 402,
|
||||
10, 57, 13, 57, 14, 57, 403, 3, 58, 3, 58, 5, 58, 408, 10, 58, 3, 58, 3,
|
||||
58, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 5, 59, 417, 10, 59, 3, 59, 5, 59,
|
||||
420, 10, 59, 3, 59, 3, 59, 3, 59, 3, 59, 3, 59, 5, 59, 427, 10, 59, 3,
|
||||
60, 6, 60, 430, 10, 60, 13, 60, 14, 60, 431, 3, 60, 3, 60, 3, 61, 3, 61,
|
||||
5, 61, 438, 10, 61, 3, 61, 5, 61, 441, 10, 61, 3, 61, 3, 61, 2, 2, 62,
|
||||
3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23,
|
||||
13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41,
|
||||
22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53, 28, 55, 29, 57, 30, 59,
|
||||
31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71, 37, 73, 2, 75, 2, 77, 2,
|
||||
79, 2, 81, 2, 83, 2, 85, 2, 87, 2, 89, 2, 91, 2, 93, 2, 95, 2, 97, 2, 99,
|
||||
2, 101, 2, 103, 2, 105, 2, 107, 2, 109, 2, 111, 2, 113, 2, 115, 2, 117,
|
||||
2, 119, 38, 121, 39, 3, 2, 17, 5, 2, 78, 78, 87, 87, 119, 119, 6, 2, 12,
|
||||
12, 15, 15, 36, 36, 94, 94, 5, 2, 67, 92, 97, 97, 99, 124, 3, 2, 50, 59,
|
||||
4, 2, 68, 68, 100, 100, 3, 2, 50, 51, 4, 2, 90, 90, 122, 122, 3, 2, 51,
|
||||
59, 3, 2, 50, 57, 5, 2, 50, 59, 67, 72, 99, 104, 4, 2, 71, 71, 103, 103,
|
||||
4, 2, 45, 45, 47, 47, 4, 2, 82, 82, 114, 114, 12, 2, 36, 36, 41, 41, 65,
|
||||
65, 94, 94, 99, 100, 104, 104, 112, 112, 116, 116, 118, 118, 120, 120,
|
||||
4, 2, 11, 11, 34, 34, 2, 467, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7,
|
||||
3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2,
|
||||
15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2,
|
||||
2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2,
|
||||
2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2,
|
||||
2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 2, 45, 3,
|
||||
2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2, 51, 3, 2, 2, 2, 2, 53,
|
||||
3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2, 2, 59, 3, 2, 2, 2, 2,
|
||||
61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 2, 67, 3, 2, 2, 2,
|
||||
2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 119, 3, 2, 2, 2, 2, 121, 3, 2,
|
||||
2, 2, 3, 123, 3, 2, 2, 2, 5, 125, 3, 2, 2, 2, 7, 127, 3, 2, 2, 2, 9, 129,
|
||||
3, 2, 2, 2, 11, 131, 3, 2, 2, 2, 13, 133, 3, 2, 2, 2, 15, 135, 3, 2, 2,
|
||||
2, 17, 138, 3, 2, 2, 2, 19, 140, 3, 2, 2, 2, 21, 143, 3, 2, 2, 2, 23, 146,
|
||||
3, 2, 2, 2, 25, 157, 3, 2, 2, 2, 27, 159, 3, 2, 2, 2, 29, 161, 3, 2, 2,
|
||||
2, 31, 163, 3, 2, 2, 2, 33, 165, 3, 2, 2, 2, 35, 167, 3, 2, 2, 2, 37, 169,
|
||||
3, 2, 2, 2, 39, 172, 3, 2, 2, 2, 41, 175, 3, 2, 2, 2, 43, 178, 3, 2, 2,
|
||||
2, 45, 180, 3, 2, 2, 2, 47, 182, 3, 2, 2, 2, 49, 189, 3, 2, 2, 2, 51, 195,
|
||||
3, 2, 2, 2, 53, 197, 3, 2, 2, 2, 55, 203, 3, 2, 2, 2, 57, 205, 3, 2, 2,
|
||||
2, 59, 208, 3, 2, 2, 2, 61, 215, 3, 2, 2, 2, 63, 252, 3, 2, 2, 2, 65, 258,
|
||||
3, 2, 2, 2, 67, 262, 3, 2, 2, 2, 69, 264, 3, 2, 2, 2, 71, 273, 3, 2, 2,
|
||||
2, 73, 284, 3, 2, 2, 2, 75, 287, 3, 2, 2, 2, 77, 298, 3, 2, 2, 2, 79, 300,
|
||||
3, 2, 2, 2, 81, 302, 3, 2, 2, 2, 83, 304, 3, 2, 2, 2, 85, 311, 3, 2, 2,
|
||||
2, 87, 318, 3, 2, 2, 2, 89, 325, 3, 2, 2, 2, 91, 329, 3, 2, 2, 2, 93, 331,
|
||||
3, 2, 2, 2, 95, 333, 3, 2, 2, 2, 97, 335, 3, 2, 2, 2, 99, 350, 3, 2, 2,
|
||||
2, 101, 359, 3, 2, 2, 2, 103, 361, 3, 2, 2, 2, 105, 377, 3, 2, 2, 2, 107,
|
||||
379, 3, 2, 2, 2, 109, 386, 3, 2, 2, 2, 111, 398, 3, 2, 2, 2, 113, 401,
|
||||
3, 2, 2, 2, 115, 405, 3, 2, 2, 2, 117, 426, 3, 2, 2, 2, 119, 429, 3, 2,
|
||||
2, 2, 121, 440, 3, 2, 2, 2, 123, 124, 7, 42, 2, 2, 124, 4, 3, 2, 2, 2,
|
||||
125, 126, 7, 43, 2, 2, 126, 6, 3, 2, 2, 2, 127, 128, 7, 93, 2, 2, 128,
|
||||
8, 3, 2, 2, 2, 129, 130, 7, 46, 2, 2, 130, 10, 3, 2, 2, 2, 131, 132, 7,
|
||||
95, 2, 2, 132, 12, 3, 2, 2, 2, 133, 134, 7, 62, 2, 2, 134, 14, 3, 2, 2,
|
||||
2, 135, 136, 7, 62, 2, 2, 136, 137, 7, 63, 2, 2, 137, 16, 3, 2, 2, 2, 138,
|
||||
139, 7, 64, 2, 2, 139, 18, 3, 2, 2, 2, 140, 141, 7, 64, 2, 2, 141, 142,
|
||||
7, 63, 2, 2, 142, 20, 3, 2, 2, 2, 143, 144, 7, 63, 2, 2, 144, 145, 7, 63,
|
||||
2, 2, 145, 22, 3, 2, 2, 2, 146, 147, 7, 35, 2, 2, 147, 148, 7, 63, 2, 2,
|
||||
148, 24, 3, 2, 2, 2, 149, 150, 7, 110, 2, 2, 150, 151, 7, 107, 2, 2, 151,
|
||||
152, 7, 109, 2, 2, 152, 158, 7, 103, 2, 2, 153, 154, 7, 78, 2, 2, 154,
|
||||
155, 7, 75, 2, 2, 155, 156, 7, 77, 2, 2, 156, 158, 7, 71, 2, 2, 157, 149,
|
||||
3, 2, 2, 2, 157, 153, 3, 2, 2, 2, 158, 26, 3, 2, 2, 2, 159, 160, 7, 45,
|
||||
2, 2, 160, 28, 3, 2, 2, 2, 161, 162, 7, 47, 2, 2, 162, 30, 3, 2, 2, 2,
|
||||
163, 164, 7, 44, 2, 2, 164, 32, 3, 2, 2, 2, 165, 166, 7, 49, 2, 2, 166,
|
||||
34, 3, 2, 2, 2, 167, 168, 7, 39, 2, 2, 168, 36, 3, 2, 2, 2, 169, 170, 7,
|
||||
44, 2, 2, 170, 171, 7, 44, 2, 2, 171, 38, 3, 2, 2, 2, 172, 173, 7, 62,
|
||||
2, 2, 173, 174, 7, 62, 2, 2, 174, 40, 3, 2, 2, 2, 175, 176, 7, 64, 2, 2,
|
||||
176, 177, 7, 64, 2, 2, 177, 42, 3, 2, 2, 2, 178, 179, 7, 40, 2, 2, 179,
|
||||
44, 3, 2, 2, 2, 180, 181, 7, 126, 2, 2, 181, 46, 3, 2, 2, 2, 182, 183,
|
||||
7, 96, 2, 2, 183, 48, 3, 2, 2, 2, 184, 185, 7, 40, 2, 2, 185, 190, 7, 40,
|
||||
2, 2, 186, 187, 7, 99, 2, 2, 187, 188, 7, 112, 2, 2, 188, 190, 7, 102,
|
||||
2, 2, 189, 184, 3, 2, 2, 2, 189, 186, 3, 2, 2, 2, 190, 50, 3, 2, 2, 2,
|
||||
191, 192, 7, 126, 2, 2, 192, 196, 7, 126, 2, 2, 193, 194, 7, 113, 2, 2,
|
||||
194, 196, 7, 116, 2, 2, 195, 191, 3, 2, 2, 2, 195, 193, 3, 2, 2, 2, 196,
|
||||
52, 3, 2, 2, 2, 197, 198, 7, 128, 2, 2, 198, 54, 3, 2, 2, 2, 199, 204,
|
||||
7, 35, 2, 2, 200, 201, 7, 112, 2, 2, 201, 202, 7, 113, 2, 2, 202, 204,
|
||||
7, 118, 2, 2, 203, 199, 3, 2, 2, 2, 203, 200, 3, 2, 2, 2, 204, 56, 3, 2,
|
||||
2, 2, 205, 206, 7, 107, 2, 2, 206, 207, 7, 112, 2, 2, 207, 58, 3, 2, 2,
|
||||
2, 208, 209, 7, 112, 2, 2, 209, 210, 7, 113, 2, 2, 210, 211, 7, 118, 2,
|
||||
2, 211, 212, 7, 34, 2, 2, 212, 213, 7, 107, 2, 2, 213, 214, 7, 112, 2,
|
||||
2, 214, 60, 3, 2, 2, 2, 215, 220, 7, 93, 2, 2, 216, 219, 5, 119, 60, 2,
|
||||
217, 219, 5, 121, 61, 2, 218, 216, 3, 2, 2, 2, 218, 217, 3, 2, 2, 2, 219,
|
||||
222, 3, 2, 2, 2, 220, 218, 3, 2, 2, 2, 220, 221, 3, 2, 2, 2, 221, 223,
|
||||
3, 2, 2, 2, 222, 220, 3, 2, 2, 2, 223, 224, 7, 95, 2, 2, 224, 62, 3, 2,
|
||||
2, 2, 225, 226, 7, 118, 2, 2, 226, 227, 7, 116, 2, 2, 227, 228, 7, 119,
|
||||
2, 2, 228, 253, 7, 103, 2, 2, 229, 230, 7, 86, 2, 2, 230, 231, 7, 116,
|
||||
2, 2, 231, 232, 7, 119, 2, 2, 232, 253, 7, 103, 2, 2, 233, 234, 7, 86,
|
||||
2, 2, 234, 235, 7, 84, 2, 2, 235, 236, 7, 87, 2, 2, 236, 253, 7, 71, 2,
|
||||
2, 237, 238, 7, 104, 2, 2, 238, 239, 7, 99, 2, 2, 239, 240, 7, 110, 2,
|
||||
2, 240, 241, 7, 117, 2, 2, 241, 253, 7, 103, 2, 2, 242, 243, 7, 72, 2,
|
||||
2, 243, 244, 7, 99, 2, 2, 244, 245, 7, 110, 2, 2, 245, 246, 7, 117, 2,
|
||||
2, 246, 253, 7, 103, 2, 2, 247, 248, 7, 72, 2, 2, 248, 249, 7, 67, 2, 2,
|
||||
249, 250, 7, 78, 2, 2, 250, 251, 7, 85, 2, 2, 251, 253, 7, 71, 2, 2, 252,
|
||||
225, 3, 2, 2, 2, 252, 229, 3, 2, 2, 2, 252, 233, 3, 2, 2, 2, 252, 237,
|
||||
3, 2, 2, 2, 252, 242, 3, 2, 2, 2, 252, 247, 3, 2, 2, 2, 253, 64, 3, 2,
|
||||
2, 2, 254, 259, 5, 85, 43, 2, 255, 259, 5, 87, 44, 2, 256, 259, 5, 89,
|
||||
45, 2, 257, 259, 5, 83, 42, 2, 258, 254, 3, 2, 2, 2, 258, 255, 3, 2, 2,
|
||||
2, 258, 256, 3, 2, 2, 2, 258, 257, 3, 2, 2, 2, 259, 66, 3, 2, 2, 2, 260,
|
||||
263, 5, 101, 51, 2, 261, 263, 5, 103, 52, 2, 262, 260, 3, 2, 2, 2, 262,
|
||||
261, 3, 2, 2, 2, 263, 68, 3, 2, 2, 2, 264, 269, 5, 79, 40, 2, 265, 268,
|
||||
5, 79, 40, 2, 266, 268, 5, 81, 41, 2, 267, 265, 3, 2, 2, 2, 267, 266, 3,
|
||||
2, 2, 2, 268, 271, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 269, 270, 3, 2, 2,
|
||||
2, 270, 70, 3, 2, 2, 2, 271, 269, 3, 2, 2, 2, 272, 274, 5, 73, 37, 2, 273,
|
||||
272, 3, 2, 2, 2, 273, 274, 3, 2, 2, 2, 274, 275, 3, 2, 2, 2, 275, 277,
|
||||
7, 36, 2, 2, 276, 278, 5, 75, 38, 2, 277, 276, 3, 2, 2, 2, 277, 278, 3,
|
||||
2, 2, 2, 278, 279, 3, 2, 2, 2, 279, 280, 7, 36, 2, 2, 280, 72, 3, 2, 2,
|
||||
2, 281, 282, 7, 119, 2, 2, 282, 285, 7, 58, 2, 2, 283, 285, 9, 2, 2, 2,
|
||||
284, 281, 3, 2, 2, 2, 284, 283, 3, 2, 2, 2, 285, 74, 3, 2, 2, 2, 286, 288,
|
||||
5, 77, 39, 2, 287, 286, 3, 2, 2, 2, 288, 289, 3, 2, 2, 2, 289, 287, 3,
|
||||
2, 2, 2, 289, 290, 3, 2, 2, 2, 290, 76, 3, 2, 2, 2, 291, 299, 10, 3, 2,
|
||||
2, 292, 299, 5, 117, 59, 2, 293, 294, 7, 94, 2, 2, 294, 299, 7, 12, 2,
|
||||
2, 295, 296, 7, 94, 2, 2, 296, 297, 7, 15, 2, 2, 297, 299, 7, 12, 2, 2,
|
||||
298, 291, 3, 2, 2, 2, 298, 292, 3, 2, 2, 2, 298, 293, 3, 2, 2, 2, 298,
|
||||
295, 3, 2, 2, 2, 299, 78, 3, 2, 2, 2, 300, 301, 9, 4, 2, 2, 301, 80, 3,
|
||||
2, 2, 2, 302, 303, 9, 5, 2, 2, 303, 82, 3, 2, 2, 2, 304, 305, 7, 50, 2,
|
||||
2, 305, 307, 9, 6, 2, 2, 306, 308, 9, 7, 2, 2, 307, 306, 3, 2, 2, 2, 308,
|
||||
309, 3, 2, 2, 2, 309, 307, 3, 2, 2, 2, 309, 310, 3, 2, 2, 2, 310, 84, 3,
|
||||
2, 2, 2, 311, 315, 5, 91, 46, 2, 312, 314, 5, 81, 41, 2, 313, 312, 3, 2,
|
||||
2, 2, 314, 317, 3, 2, 2, 2, 315, 313, 3, 2, 2, 2, 315, 316, 3, 2, 2, 2,
|
||||
316, 86, 3, 2, 2, 2, 317, 315, 3, 2, 2, 2, 318, 322, 7, 50, 2, 2, 319,
|
||||
321, 5, 93, 47, 2, 320, 319, 3, 2, 2, 2, 321, 324, 3, 2, 2, 2, 322, 320,
|
||||
3, 2, 2, 2, 322, 323, 3, 2, 2, 2, 323, 88, 3, 2, 2, 2, 324, 322, 3, 2,
|
||||
2, 2, 325, 326, 7, 50, 2, 2, 326, 327, 9, 8, 2, 2, 327, 328, 5, 113, 57,
|
||||
2, 328, 90, 3, 2, 2, 2, 329, 330, 9, 9, 2, 2, 330, 92, 3, 2, 2, 2, 331,
|
||||
332, 9, 10, 2, 2, 332, 94, 3, 2, 2, 2, 333, 334, 9, 11, 2, 2, 334, 96,
|
||||
3, 2, 2, 2, 335, 336, 5, 95, 48, 2, 336, 337, 5, 95, 48, 2, 337, 338, 5,
|
||||
95, 48, 2, 338, 339, 5, 95, 48, 2, 339, 98, 3, 2, 2, 2, 340, 341, 7, 94,
|
||||
2, 2, 341, 342, 7, 119, 2, 2, 342, 343, 3, 2, 2, 2, 343, 351, 5, 97, 49,
|
||||
2, 344, 345, 7, 94, 2, 2, 345, 346, 7, 87, 2, 2, 346, 347, 3, 2, 2, 2,
|
||||
347, 348, 5, 97, 49, 2, 348, 349, 5, 97, 49, 2, 349, 351, 3, 2, 2, 2, 350,
|
||||
340, 3, 2, 2, 2, 350, 344, 3, 2, 2, 2, 351, 100, 3, 2, 2, 2, 352, 354,
|
||||
5, 105, 53, 2, 353, 355, 5, 107, 54, 2, 354, 353, 3, 2, 2, 2, 354, 355,
|
||||
3, 2, 2, 2, 355, 360, 3, 2, 2, 2, 356, 357, 5, 109, 55, 2, 357, 358, 5,
|
||||
107, 54, 2, 358, 360, 3, 2, 2, 2, 359, 352, 3, 2, 2, 2, 359, 356, 3, 2,
|
||||
2, 2, 360, 102, 3, 2, 2, 2, 361, 362, 7, 50, 2, 2, 362, 365, 9, 8, 2, 2,
|
||||
363, 366, 5, 111, 56, 2, 364, 366, 5, 113, 57, 2, 365, 363, 3, 2, 2, 2,
|
||||
365, 364, 3, 2, 2, 2, 366, 367, 3, 2, 2, 2, 367, 368, 5, 115, 58, 2, 368,
|
||||
104, 3, 2, 2, 2, 369, 371, 5, 109, 55, 2, 370, 369, 3, 2, 2, 2, 370, 371,
|
||||
3, 2, 2, 2, 371, 372, 3, 2, 2, 2, 372, 373, 7, 48, 2, 2, 373, 378, 5, 109,
|
||||
55, 2, 374, 375, 5, 109, 55, 2, 375, 376, 7, 48, 2, 2, 376, 378, 3, 2,
|
||||
2, 2, 377, 370, 3, 2, 2, 2, 377, 374, 3, 2, 2, 2, 378, 106, 3, 2, 2, 2,
|
||||
379, 381, 9, 12, 2, 2, 380, 382, 9, 13, 2, 2, 381, 380, 3, 2, 2, 2, 381,
|
||||
382, 3, 2, 2, 2, 382, 383, 3, 2, 2, 2, 383, 384, 5, 109, 55, 2, 384, 108,
|
||||
3, 2, 2, 2, 385, 387, 5, 81, 41, 2, 386, 385, 3, 2, 2, 2, 387, 388, 3,
|
||||
2, 2, 2, 388, 386, 3, 2, 2, 2, 388, 389, 3, 2, 2, 2, 389, 110, 3, 2, 2,
|
||||
2, 390, 392, 5, 113, 57, 2, 391, 390, 3, 2, 2, 2, 391, 392, 3, 2, 2, 2,
|
||||
392, 393, 3, 2, 2, 2, 393, 394, 7, 48, 2, 2, 394, 399, 5, 113, 57, 2, 395,
|
||||
396, 5, 113, 57, 2, 396, 397, 7, 48, 2, 2, 397, 399, 3, 2, 2, 2, 398, 391,
|
||||
3, 2, 2, 2, 398, 395, 3, 2, 2, 2, 399, 112, 3, 2, 2, 2, 400, 402, 5, 95,
|
||||
48, 2, 401, 400, 3, 2, 2, 2, 402, 403, 3, 2, 2, 2, 403, 401, 3, 2, 2, 2,
|
||||
403, 404, 3, 2, 2, 2, 404, 114, 3, 2, 2, 2, 405, 407, 9, 14, 2, 2, 406,
|
||||
408, 9, 13, 2, 2, 407, 406, 3, 2, 2, 2, 407, 408, 3, 2, 2, 2, 408, 409,
|
||||
3, 2, 2, 2, 409, 410, 5, 109, 55, 2, 410, 116, 3, 2, 2, 2, 411, 412, 7,
|
||||
94, 2, 2, 412, 427, 9, 15, 2, 2, 413, 414, 7, 94, 2, 2, 414, 416, 5, 93,
|
||||
47, 2, 415, 417, 5, 93, 47, 2, 416, 415, 3, 2, 2, 2, 416, 417, 3, 2, 2,
|
||||
2, 417, 419, 3, 2, 2, 2, 418, 420, 5, 93, 47, 2, 419, 418, 3, 2, 2, 2,
|
||||
419, 420, 3, 2, 2, 2, 420, 427, 3, 2, 2, 2, 421, 422, 7, 94, 2, 2, 422,
|
||||
423, 7, 122, 2, 2, 423, 424, 3, 2, 2, 2, 424, 427, 5, 113, 57, 2, 425,
|
||||
427, 5, 99, 50, 2, 426, 411, 3, 2, 2, 2, 426, 413, 3, 2, 2, 2, 426, 421,
|
||||
3, 2, 2, 2, 426, 425, 3, 2, 2, 2, 427, 118, 3, 2, 2, 2, 428, 430, 9, 16,
|
||||
2, 2, 429, 428, 3, 2, 2, 2, 430, 431, 3, 2, 2, 2, 431, 429, 3, 2, 2, 2,
|
||||
431, 432, 3, 2, 2, 2, 432, 433, 3, 2, 2, 2, 433, 434, 8, 60, 2, 2, 434,
|
||||
120, 3, 2, 2, 2, 435, 437, 7, 15, 2, 2, 436, 438, 7, 12, 2, 2, 437, 436,
|
||||
3, 2, 2, 2, 437, 438, 3, 2, 2, 2, 438, 441, 3, 2, 2, 2, 439, 441, 7, 12,
|
||||
2, 2, 440, 435, 3, 2, 2, 2, 440, 439, 3, 2, 2, 2, 441, 442, 3, 2, 2, 2,
|
||||
442, 443, 8, 61, 2, 2, 443, 122, 3, 2, 2, 2, 40, 2, 157, 189, 195, 203,
|
||||
218, 220, 252, 258, 262, 267, 269, 273, 277, 284, 289, 298, 309, 315, 322,
|
||||
350, 354, 359, 365, 370, 377, 381, 388, 391, 398, 403, 407, 416, 419, 426,
|
||||
431, 437, 440, 3, 8, 2, 2,
|
||||
}
|
||||
|
||||
var lexerChannelNames = []string{
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
|
||||
}
|
||||
|
||||
var lexerModeNames = []string{
|
||||
"DEFAULT_MODE",
|
||||
}
|
||||
|
||||
var lexerLiteralNames = []string{
|
||||
"", "'('", "')'", "'['", "','", "']'", "'<'", "'<='", "'>'", "'>='", "'=='",
|
||||
"'!='", "", "'+'", "'-'", "'*'", "'/'", "'%'", "'**'", "'<<'", "'>>'",
|
||||
"'&'", "'|'", "'^'", "", "", "'~'", "", "'in'", "'not in'",
|
||||
}
|
||||
|
||||
var lexerSymbolicNames = []string{
|
||||
"", "", "", "", "", "", "LT", "LE", "GT", "GE", "EQ", "NE", "LIKE", "ADD",
|
||||
"SUB", "MUL", "DIV", "MOD", "POW", "SHL", "SHR", "BAND", "BOR", "BXOR",
|
||||
"AND", "OR", "BNOT", "NOT", "IN", "NIN", "EmptyTerm", "BooleanConstant",
|
||||
"IntegerConstant", "FloatingConstant", "Identifier", "StringLiteral", "Whitespace",
|
||||
"Newline",
|
||||
}
|
||||
|
||||
var lexerRuleNames = []string{
|
||||
"T__0", "T__1", "T__2", "T__3", "T__4", "LT", "LE", "GT", "GE", "EQ", "NE",
|
||||
"LIKE", "ADD", "SUB", "MUL", "DIV", "MOD", "POW", "SHL", "SHR", "BAND",
|
||||
"BOR", "BXOR", "AND", "OR", "BNOT", "NOT", "IN", "NIN", "EmptyTerm", "BooleanConstant",
|
||||
"IntegerConstant", "FloatingConstant", "Identifier", "StringLiteral", "EncodingPrefix",
|
||||
"SCharSequence", "SChar", "Nondigit", "Digit", "BinaryConstant", "DecimalConstant",
|
||||
"OctalConstant", "HexadecimalConstant", "NonzeroDigit", "OctalDigit", "HexadecimalDigit",
|
||||
"HexQuad", "UniversalCharacterName", "DecimalFloatingConstant", "HexadecimalFloatingConstant",
|
||||
"FractionalConstant", "ExponentPart", "DigitSequence", "HexadecimalFractionalConstant",
|
||||
"HexadecimalDigitSequence", "BinaryExponentPart", "EscapeSequence", "Whitespace",
|
||||
"Newline",
|
||||
}
|
||||
|
||||
type PlanLexer struct {
|
||||
*antlr.BaseLexer
|
||||
channelNames []string
|
||||
modeNames []string
|
||||
// TODO: EOF string
|
||||
}
|
||||
|
||||
// NewPlanLexer produces a new lexer instance for the optional input antlr.CharStream.
|
||||
//
|
||||
// The *PlanLexer instance produced may be reused by calling the SetInputStream method.
|
||||
// The initial lexer configuration is expensive to construct, and the object is not thread-safe;
|
||||
// however, if used within a Golang sync.Pool, the construction cost amortizes well and the
|
||||
// objects can be used in a thread-safe manner.
|
||||
func NewPlanLexer(input antlr.CharStream) *PlanLexer {
|
||||
l := new(PlanLexer)
|
||||
lexerDeserializer := antlr.NewATNDeserializer(nil)
|
||||
lexerAtn := lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn)
|
||||
lexerDecisionToDFA := make([]*antlr.DFA, len(lexerAtn.DecisionToState))
|
||||
for index, ds := range lexerAtn.DecisionToState {
|
||||
lexerDecisionToDFA[index] = antlr.NewDFA(ds, index)
|
||||
}
|
||||
l.BaseLexer = antlr.NewBaseLexer(input)
|
||||
l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache())
|
||||
|
||||
l.channelNames = lexerChannelNames
|
||||
l.modeNames = lexerModeNames
|
||||
l.RuleNames = lexerRuleNames
|
||||
l.LiteralNames = lexerLiteralNames
|
||||
l.SymbolicNames = lexerSymbolicNames
|
||||
l.GrammarFileName = "Plan.g4"
|
||||
// TODO: l.EOF = antlr.TokenEOF
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
// PlanLexer tokens.
|
||||
const (
|
||||
PlanLexerT__0 = 1
|
||||
PlanLexerT__1 = 2
|
||||
PlanLexerT__2 = 3
|
||||
PlanLexerT__3 = 4
|
||||
PlanLexerT__4 = 5
|
||||
PlanLexerLT = 6
|
||||
PlanLexerLE = 7
|
||||
PlanLexerGT = 8
|
||||
PlanLexerGE = 9
|
||||
PlanLexerEQ = 10
|
||||
PlanLexerNE = 11
|
||||
PlanLexerLIKE = 12
|
||||
PlanLexerADD = 13
|
||||
PlanLexerSUB = 14
|
||||
PlanLexerMUL = 15
|
||||
PlanLexerDIV = 16
|
||||
PlanLexerMOD = 17
|
||||
PlanLexerPOW = 18
|
||||
PlanLexerSHL = 19
|
||||
PlanLexerSHR = 20
|
||||
PlanLexerBAND = 21
|
||||
PlanLexerBOR = 22
|
||||
PlanLexerBXOR = 23
|
||||
PlanLexerAND = 24
|
||||
PlanLexerOR = 25
|
||||
PlanLexerBNOT = 26
|
||||
PlanLexerNOT = 27
|
||||
PlanLexerIN = 28
|
||||
PlanLexerNIN = 29
|
||||
PlanLexerEmptyTerm = 30
|
||||
PlanLexerBooleanConstant = 31
|
||||
PlanLexerIntegerConstant = 32
|
||||
PlanLexerFloatingConstant = 33
|
||||
PlanLexerIdentifier = 34
|
||||
PlanLexerStringLiteral = 35
|
||||
PlanLexerWhitespace = 36
|
||||
PlanLexerNewline = 37
|
||||
)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,78 @@
|
|||
// Code generated from Plan.g4 by ANTLR 4.9. DO NOT EDIT.
|
||||
|
||||
package planparserv2 // Plan
|
||||
import "github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
// A complete Visitor for a parse tree produced by PlanParser.
|
||||
type PlanVisitor interface {
|
||||
antlr.ParseTreeVisitor
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Shift.
|
||||
VisitShift(ctx *ShiftContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#ReverseRange.
|
||||
VisitReverseRange(ctx *ReverseRangeContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#BitOr.
|
||||
VisitBitOr(ctx *BitOrContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#AddSub.
|
||||
VisitAddSub(ctx *AddSubContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Parens.
|
||||
VisitParens(ctx *ParensContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Relational.
|
||||
VisitRelational(ctx *RelationalContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#String.
|
||||
VisitString(ctx *StringContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Term.
|
||||
VisitTerm(ctx *TermContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Floating.
|
||||
VisitFloating(ctx *FloatingContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Range.
|
||||
VisitRange(ctx *RangeContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Unary.
|
||||
VisitUnary(ctx *UnaryContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#LogicalOr.
|
||||
VisitLogicalOr(ctx *LogicalOrContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Integer.
|
||||
VisitInteger(ctx *IntegerContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#MulDivMod.
|
||||
VisitMulDivMod(ctx *MulDivModContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Identifier.
|
||||
VisitIdentifier(ctx *IdentifierContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#BitXor.
|
||||
VisitBitXor(ctx *BitXorContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Like.
|
||||
VisitLike(ctx *LikeContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#BitAnd.
|
||||
VisitBitAnd(ctx *BitAndContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#LogicalAnd.
|
||||
VisitLogicalAnd(ctx *LogicalAndContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#EmptyTerm.
|
||||
VisitEmptyTerm(ctx *EmptyTermContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Equality.
|
||||
VisitEquality(ctx *EqualityContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Boolean.
|
||||
VisitBoolean(ctx *BooleanContext) interface{}
|
||||
|
||||
// Visit a parse tree produced by PlanParser#Power.
|
||||
VisitPower(ctx *PowerContext) interface{}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package planparserv2
|
||||
|
||||
import "github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
|
||||
type LogicalExprVisitor interface {
|
||||
VisitExpr(expr *planpb.Expr) interface{}
|
||||
VisitTermExpr(expr *planpb.TermExpr) interface{}
|
||||
VisitUnaryExpr(expr *planpb.UnaryExpr) interface{}
|
||||
VisitBinaryExpr(expr *planpb.BinaryExpr) interface{}
|
||||
VisitCompareExpr(expr *planpb.CompareExpr) interface{}
|
||||
VisitUnaryRangeExpr(expr *planpb.UnaryRangeExpr) interface{}
|
||||
VisitBinaryRangeExpr(expr *planpb.BinaryRangeExpr) interface{}
|
||||
VisitBinaryArithOpEvalRangeExpr(expr *planpb.BinaryArithOpEvalRangeExpr) interface{}
|
||||
VisitBinaryArithExpr(expr *planpb.BinaryArithExpr) interface{}
|
||||
VisitValueExpr(expr *planpb.ValueExpr) interface{}
|
||||
VisitColumnExpr(expr *planpb.ColumnExpr) interface{}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
)
|
||||
|
||||
type ExprWithType struct {
|
||||
expr *planpb.Expr
|
||||
dataType schemapb.DataType
|
||||
}
|
||||
|
||||
func getError(obj interface{}) error {
|
||||
err, ok := obj.(error)
|
||||
if !ok {
|
||||
// obj is not an error.
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func getExpr(obj interface{}) *ExprWithType {
|
||||
n, ok := obj.(*ExprWithType)
|
||||
if !ok {
|
||||
// obj is not of *ExprWithType
|
||||
return nil
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func getGenericValue(obj interface{}) *planpb.GenericValue {
|
||||
expr := getExpr(obj)
|
||||
if expr == nil {
|
||||
return nil
|
||||
}
|
||||
return expr.expr.GetValueExpr().GetValue()
|
||||
}
|
|
@ -0,0 +1,633 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
parser "github.com/milvus-io/milvus/internal/parser/planparserv2/generated"
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
)
|
||||
|
||||
var arithExprMap = map[int]planpb.ArithOpType{
|
||||
parser.PlanParserADD: planpb.ArithOpType_Add,
|
||||
parser.PlanParserSUB: planpb.ArithOpType_Sub,
|
||||
parser.PlanParserMUL: planpb.ArithOpType_Mul,
|
||||
parser.PlanParserDIV: planpb.ArithOpType_Div,
|
||||
parser.PlanParserMOD: planpb.ArithOpType_Mod,
|
||||
}
|
||||
|
||||
var arithNameMap = map[int]string{
|
||||
parser.PlanParserADD: "add",
|
||||
parser.PlanParserSUB: "subtract",
|
||||
parser.PlanParserMUL: "multiply",
|
||||
parser.PlanParserDIV: "divide",
|
||||
parser.PlanParserMOD: "modulo",
|
||||
}
|
||||
|
||||
var cmpOpMap = map[int]planpb.OpType{
|
||||
parser.PlanParserLT: planpb.OpType_LessThan,
|
||||
parser.PlanParserLE: planpb.OpType_LessEqual,
|
||||
parser.PlanParserGT: planpb.OpType_GreaterThan,
|
||||
parser.PlanParserGE: planpb.OpType_GreaterEqual,
|
||||
parser.PlanParserEQ: planpb.OpType_Equal,
|
||||
parser.PlanParserNE: planpb.OpType_NotEqual,
|
||||
}
|
||||
|
||||
var cmpNameMap = map[int]string{
|
||||
parser.PlanParserLT: "less",
|
||||
parser.PlanParserLE: "lessequal",
|
||||
parser.PlanParserGT: "greater",
|
||||
parser.PlanParserGE: "greaterequal",
|
||||
parser.PlanParserEQ: "equal",
|
||||
parser.PlanParserNE: "notequal",
|
||||
}
|
||||
|
||||
var unaryLogicalOpMap = map[int]planpb.UnaryExpr_UnaryOp{
|
||||
parser.PlanParserNOT: planpb.UnaryExpr_Not,
|
||||
}
|
||||
|
||||
var unaryLogicalNameMap = map[int]string{
|
||||
parser.PlanParserNOT: "not",
|
||||
}
|
||||
|
||||
var binaryLogicalOpMap = map[int]planpb.BinaryExpr_BinaryOp{
|
||||
parser.PlanParserAND: planpb.BinaryExpr_LogicalAnd,
|
||||
parser.PlanParserOR: planpb.BinaryExpr_LogicalOr,
|
||||
}
|
||||
|
||||
var binaryLogicalNameMap = map[int]string{
|
||||
parser.PlanParserAND: "and",
|
||||
parser.PlanParserOR: "or",
|
||||
}
|
||||
|
||||
func Add(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if IsBool(a) || IsBool(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if IsString(a) || IsString(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
|
||||
if aFloat && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() + b.GetFloatVal())
|
||||
} else if aFloat && bInt {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() + float64(b.GetInt64Val()))
|
||||
} else if aInt && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(float64(a.GetInt64Val()) + b.GetFloatVal())
|
||||
} else {
|
||||
// aInt && bInt
|
||||
ret.dataType = schemapb.DataType_Int64
|
||||
ret.expr.GetValueExpr().Value = NewInt(a.GetInt64Val() + b.GetInt64Val())
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func Subtract(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if IsBool(a) || IsBool(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if IsString(a) || IsString(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
|
||||
if aFloat && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() - b.GetFloatVal())
|
||||
} else if aFloat && bInt {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() - float64(b.GetInt64Val()))
|
||||
} else if aInt && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(float64(a.GetInt64Val()) - b.GetFloatVal())
|
||||
} else {
|
||||
// aInt && bInt
|
||||
ret.dataType = schemapb.DataType_Int64
|
||||
ret.expr.GetValueExpr().Value = NewInt(a.GetInt64Val() - b.GetInt64Val())
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func Multiply(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if IsBool(a) || IsBool(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if IsString(a) || IsString(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
|
||||
if aFloat && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() * b.GetFloatVal())
|
||||
} else if aFloat && bInt {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() * float64(b.GetInt64Val()))
|
||||
} else if aInt && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(float64(a.GetInt64Val()) * b.GetFloatVal())
|
||||
} else {
|
||||
// aInt && bInt
|
||||
ret.dataType = schemapb.DataType_Int64
|
||||
ret.expr.GetValueExpr().Value = NewInt(a.GetInt64Val() * b.GetInt64Val())
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func Divide(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
ret := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if IsBool(a) || IsBool(b) {
|
||||
return nil, fmt.Errorf("divide cannot apply on bool field")
|
||||
}
|
||||
|
||||
if IsString(a) || IsString(b) {
|
||||
return nil, fmt.Errorf("divide cannot apply on string field")
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
|
||||
if bFloat && b.GetFloatVal() == 0 {
|
||||
return nil, fmt.Errorf("cannot divide by zero")
|
||||
}
|
||||
|
||||
if bInt && b.GetInt64Val() == 0 {
|
||||
return nil, fmt.Errorf("cannot divide by zero")
|
||||
}
|
||||
|
||||
if aFloat && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() / b.GetFloatVal())
|
||||
} else if aFloat && bInt {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(a.GetFloatVal() / float64(b.GetInt64Val()))
|
||||
} else if aInt && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(float64(a.GetInt64Val()) / b.GetFloatVal())
|
||||
} else {
|
||||
// aInt && bInt
|
||||
ret.dataType = schemapb.DataType_Int64
|
||||
ret.expr.GetValueExpr().Value = NewInt(a.GetInt64Val() / b.GetInt64Val())
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func Modulo(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
ret := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
aInt, bInt := IsInteger(a), IsInteger(b)
|
||||
if !aInt || !bInt {
|
||||
return nil, fmt.Errorf("modulo can only apply on integer")
|
||||
}
|
||||
|
||||
// aInt && bInt
|
||||
if b.GetInt64Val() == 0 {
|
||||
return nil, fmt.Errorf("cannot modulo by zero")
|
||||
}
|
||||
|
||||
ret.dataType = schemapb.DataType_Int64
|
||||
ret.expr.GetValueExpr().Value = NewInt(a.GetInt64Val() % b.GetInt64Val())
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func Power(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if IsBool(a) || IsBool(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if IsString(a) || IsString(b) {
|
||||
return nil
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
|
||||
if aFloat && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(math.Pow(a.GetFloatVal(), b.GetFloatVal()))
|
||||
} else if aFloat && bInt {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(math.Pow(a.GetFloatVal(), float64(b.GetInt64Val())))
|
||||
} else if aInt && bFloat {
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(math.Pow(float64(a.GetInt64Val()), b.GetFloatVal()))
|
||||
} else {
|
||||
// aInt && bInt
|
||||
// 2 ** (-1) = 0.5
|
||||
ret.dataType = schemapb.DataType_Double
|
||||
ret.expr.GetValueExpr().Value = NewFloat(math.Pow(float64(a.GetInt64Val()), float64(b.GetInt64Val())))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func BitAnd(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
return nil, fmt.Errorf("todo: unsupported")
|
||||
}
|
||||
|
||||
func BitOr(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
return nil, fmt.Errorf("todo: unsupported")
|
||||
}
|
||||
|
||||
func BitXor(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
return nil, fmt.Errorf("todo: unsupported")
|
||||
}
|
||||
|
||||
func ShiftLeft(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
return nil, fmt.Errorf("todo: unsupported")
|
||||
}
|
||||
|
||||
func ShiftRight(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
return nil, fmt.Errorf("todo: unsupported")
|
||||
}
|
||||
|
||||
func And(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
aBool, bBool := IsBool(a), IsBool(b)
|
||||
if !aBool || !bBool {
|
||||
return nil, fmt.Errorf("and can only apply on boolean")
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewBool(a.GetBoolVal() && b.GetBoolVal()),
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Or(a, b *planpb.GenericValue) (*ExprWithType, error) {
|
||||
aBool, bBool := IsBool(a), IsBool(b)
|
||||
if !aBool || !bBool {
|
||||
return nil, fmt.Errorf("or can only apply on boolean")
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewBool(a.GetBoolVal() || b.GetBoolVal()),
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func BitNot(a *planpb.GenericValue) (*ExprWithType, error) {
|
||||
return nil, fmt.Errorf("todo: unsupported")
|
||||
}
|
||||
|
||||
func Negative(a *planpb.GenericValue) *ExprWithType {
|
||||
if IsFloating(a) {
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Double,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewFloat(-a.GetFloatVal()),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
if IsInteger(a) {
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Int64,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewInt(-a.GetInt64Val()),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Not(a *planpb.GenericValue) *ExprWithType {
|
||||
if !IsBool(a) {
|
||||
return nil
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewBool(!a.GetBoolVal()),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
type relationalFn func(a, b *planpb.GenericValue) (bool, error)
|
||||
|
||||
func applyRelational(a, b *planpb.GenericValue, relational relationalFn) *ExprWithType {
|
||||
ret, err := relational(a, b)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewBool(ret),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func less() relationalFn {
|
||||
return func(a, b *planpb.GenericValue) (bool, error) {
|
||||
if IsString(a) && IsString(b) {
|
||||
return a.GetStringVal() < b.GetStringVal(), nil
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
if aFloat && bFloat {
|
||||
return a.GetFloatVal() < b.GetFloatVal(), nil
|
||||
} else if aFloat && bInt {
|
||||
return a.GetFloatVal() < float64(b.GetInt64Val()), nil
|
||||
} else if aInt && bFloat {
|
||||
return float64(a.GetInt64Val()) < b.GetFloatVal(), nil
|
||||
} else if aInt && bInt {
|
||||
return a.GetInt64Val() < b.GetInt64Val(), nil
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("incompatible data type")
|
||||
}
|
||||
}
|
||||
|
||||
func Less(a, b *planpb.GenericValue) *ExprWithType {
|
||||
return applyRelational(a, b, less())
|
||||
}
|
||||
|
||||
// TODO: Can we abstract these relational function?
|
||||
*/
|
||||
|
||||
func Less(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
if IsString(a) && IsString(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetStringVal() < b.GetStringVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
if aFloat && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() < b.GetFloatVal())
|
||||
return ret
|
||||
} else if aFloat && bInt {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() < float64(b.GetInt64Val()))
|
||||
return ret
|
||||
} else if aInt && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(float64(a.GetInt64Val()) < b.GetFloatVal())
|
||||
return ret
|
||||
} else if aInt && bInt {
|
||||
// aInt && bInt
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetInt64Val() < b.GetInt64Val())
|
||||
return ret
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func LessEqual(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
if IsString(a) && IsString(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetStringVal() <= b.GetStringVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
if aFloat && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() <= b.GetFloatVal())
|
||||
return ret
|
||||
} else if aFloat && bInt {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() <= float64(b.GetInt64Val()))
|
||||
return ret
|
||||
} else if aInt && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(float64(a.GetInt64Val()) <= b.GetFloatVal())
|
||||
return ret
|
||||
} else if aInt && bInt {
|
||||
// aInt && bInt
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetInt64Val() <= b.GetInt64Val())
|
||||
return ret
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Greater(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
if IsString(a) && IsString(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetStringVal() > b.GetStringVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
if aFloat && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() > b.GetFloatVal())
|
||||
return ret
|
||||
} else if aFloat && bInt {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() > float64(b.GetInt64Val()))
|
||||
return ret
|
||||
} else if aInt && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(float64(a.GetInt64Val()) > b.GetFloatVal())
|
||||
return ret
|
||||
} else if aInt && bInt {
|
||||
// aInt && bInt
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetInt64Val() > b.GetInt64Val())
|
||||
return ret
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GreaterEqual(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
if IsString(a) && IsString(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetStringVal() >= b.GetStringVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
if aFloat && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() >= b.GetFloatVal())
|
||||
return ret
|
||||
} else if aFloat && bInt {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetFloatVal() >= float64(b.GetInt64Val()))
|
||||
return ret
|
||||
} else if aInt && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(float64(a.GetInt64Val()) >= b.GetFloatVal())
|
||||
return ret
|
||||
} else if aInt && bInt {
|
||||
// aInt && bInt
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetInt64Val() >= b.GetInt64Val())
|
||||
return ret
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func Equal(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
if IsBool(a) && IsBool(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetBoolVal() == b.GetBoolVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
if IsString(a) && IsString(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetStringVal() == b.GetStringVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
if aFloat && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(floatingEqual(a.GetFloatVal(), b.GetFloatVal()))
|
||||
return ret
|
||||
} else if aFloat && bInt {
|
||||
ret.expr.GetValueExpr().Value = NewBool(floatingEqual(a.GetFloatVal(), float64(b.GetInt64Val())))
|
||||
return ret
|
||||
} else if aInt && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(floatingEqual(float64(a.GetInt64Val()), b.GetFloatVal()))
|
||||
return ret
|
||||
} else if aInt && bInt {
|
||||
// aInt && bInt
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetInt64Val() == b.GetInt64Val())
|
||||
return ret
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NotEqual(a, b *planpb.GenericValue) *ExprWithType {
|
||||
ret := &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{},
|
||||
},
|
||||
},
|
||||
}
|
||||
if IsBool(a) && IsBool(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetBoolVal() != b.GetBoolVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
if IsString(a) && IsString(b) {
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetStringVal() != b.GetStringVal())
|
||||
return ret
|
||||
}
|
||||
|
||||
aFloat, bFloat, aInt, bInt := IsFloating(a), IsFloating(b), IsInteger(a), IsInteger(b)
|
||||
if aFloat && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(!floatingEqual(a.GetFloatVal(), b.GetFloatVal()))
|
||||
return ret
|
||||
} else if aFloat && bInt {
|
||||
ret.expr.GetValueExpr().Value = NewBool(!floatingEqual(a.GetFloatVal(), float64(b.GetInt64Val())))
|
||||
return ret
|
||||
} else if aInt && bFloat {
|
||||
ret.expr.GetValueExpr().Value = NewBool(!floatingEqual(float64(a.GetInt64Val()), b.GetFloatVal()))
|
||||
return ret
|
||||
} else if aInt && bInt {
|
||||
// aInt && bInt
|
||||
ret.expr.GetValueExpr().Value = NewBool(a.GetInt64Val() != b.GetInt64Val())
|
||||
return ret
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,877 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
parser "github.com/milvus-io/milvus/internal/parser/planparserv2/generated"
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
)
|
||||
|
||||
type ParserVisitor struct {
|
||||
parser.BasePlanVisitor
|
||||
schema *typeutil.SchemaHelper
|
||||
}
|
||||
|
||||
func NewParserVisitor(schema *typeutil.SchemaHelper) *ParserVisitor {
|
||||
return &ParserVisitor{schema: schema}
|
||||
}
|
||||
|
||||
// VisitParens unpack the parentheses.
|
||||
func (v *ParserVisitor) VisitParens(ctx *parser.ParensContext) interface{} {
|
||||
return ctx.Expr().Accept(v)
|
||||
}
|
||||
|
||||
// VisitIdentifier translates expr to column plan.
|
||||
func (v *ParserVisitor) VisitIdentifier(ctx *parser.IdentifierContext) interface{} {
|
||||
fieldName := ctx.Identifier().GetText()
|
||||
field, err := v.schema.GetFieldFromName(fieldName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ColumnExpr{
|
||||
ColumnExpr: &planpb.ColumnExpr{
|
||||
Info: &planpb.ColumnInfo{
|
||||
FieldId: field.FieldID,
|
||||
DataType: field.DataType,
|
||||
IsPrimaryKey: field.IsPrimaryKey,
|
||||
IsAutoID: field.AutoID,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: field.DataType,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitBoolean translates expr to GenericValue.
|
||||
func (v *ParserVisitor) VisitBoolean(ctx *parser.BooleanContext) interface{} {
|
||||
literal := ctx.BooleanConstant().GetText()
|
||||
b, err := strconv.ParseBool(literal)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Bool,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewBool(b),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VisitInteger translates expr to GenericValue.
|
||||
func (v *ParserVisitor) VisitInteger(ctx *parser.IntegerContext) interface{} {
|
||||
literal := ctx.IntegerConstant().GetText()
|
||||
i, err := strconv.ParseInt(literal, 0, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Int64,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewInt(i),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VisitFloating translates expr to GenericValue.
|
||||
func (v *ParserVisitor) VisitFloating(ctx *parser.FloatingContext) interface{} {
|
||||
literal := ctx.FloatingConstant().GetText()
|
||||
f, err := strconv.ParseFloat(literal, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_Double,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewFloat(f),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VisitString translates expr to GenericValue.
|
||||
func (v *ParserVisitor) VisitString(ctx *parser.StringContext) interface{} {
|
||||
literal, err := strconv.Unquote(ctx.StringLiteral().GetText())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return &ExprWithType{
|
||||
dataType: schemapb.DataType_VarChar,
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: NewString(literal),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// VisitAddSub translates expr to arithmetic plan.
|
||||
func (v *ParserVisitor) VisitAddSub(ctx *parser.AddSubContext) interface{} {
|
||||
left := ctx.Expr(0).Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
right := ctx.Expr(1).Accept(v)
|
||||
if err := getError(right); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftValue, rightValue := getGenericValue(left), getGenericValue(right)
|
||||
if leftValue != nil && rightValue != nil {
|
||||
switch ctx.GetOp().GetTokenType() {
|
||||
case parser.PlanParserADD:
|
||||
return Add(leftValue, rightValue)
|
||||
case parser.PlanParserSUB:
|
||||
return Subtract(leftValue, rightValue)
|
||||
default:
|
||||
return fmt.Errorf("unexpected op: %s", ctx.GetOp().GetText())
|
||||
}
|
||||
}
|
||||
|
||||
var leftExpr *ExprWithType
|
||||
var rightExpr *ExprWithType
|
||||
reverse := true
|
||||
|
||||
if leftValue != nil {
|
||||
leftExpr = toValueExpr(leftValue)
|
||||
} else {
|
||||
reverse = false
|
||||
leftExpr = getExpr(left)
|
||||
}
|
||||
if rightValue != nil {
|
||||
rightExpr = toValueExpr(rightValue)
|
||||
} else {
|
||||
rightExpr = getExpr(right)
|
||||
}
|
||||
|
||||
if leftExpr == nil || rightExpr == nil {
|
||||
return fmt.Errorf("invalid arithmetic expression, left: %s, op: %s, right: %s", ctx.Expr(0).GetText(), ctx.GetOp(), ctx.Expr(1).GetText())
|
||||
}
|
||||
|
||||
if !typeutil.IsArithmetic(leftExpr.dataType) || !typeutil.IsArithmetic(rightExpr.dataType) {
|
||||
return fmt.Errorf("'%s' can only be used between integer or floating expressions", arithNameMap[ctx.GetOp().GetTokenType()])
|
||||
}
|
||||
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_BinaryArithExpr{
|
||||
BinaryArithExpr: &planpb.BinaryArithExpr{
|
||||
Left: leftExpr.expr,
|
||||
Right: rightExpr.expr,
|
||||
Op: arithExprMap[ctx.GetOp().GetTokenType()],
|
||||
},
|
||||
},
|
||||
}
|
||||
dataType, err := calcDataType(leftExpr, rightExpr, reverse)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: dataType,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitMulDivMod translates expr to arithmetic plan.
|
||||
func (v *ParserVisitor) VisitMulDivMod(ctx *parser.MulDivModContext) interface{} {
|
||||
left := ctx.Expr(0).Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
right := ctx.Expr(1).Accept(v)
|
||||
if err := getError(right); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftValue, rightValue := getGenericValue(left), getGenericValue(right)
|
||||
if leftValue != nil && rightValue != nil {
|
||||
switch ctx.GetOp().GetTokenType() {
|
||||
case parser.PlanParserMUL:
|
||||
return Multiply(leftValue, rightValue)
|
||||
case parser.PlanParserDIV:
|
||||
n, err := Divide(leftValue, rightValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n
|
||||
case parser.PlanParserMOD:
|
||||
n, err := Modulo(leftValue, rightValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n
|
||||
default:
|
||||
return fmt.Errorf("unexpected op: %s", ctx.GetOp().GetText())
|
||||
}
|
||||
}
|
||||
|
||||
var leftExpr *ExprWithType
|
||||
var rightExpr *ExprWithType
|
||||
reverse := true
|
||||
|
||||
if leftValue != nil {
|
||||
leftExpr = toValueExpr(leftValue)
|
||||
} else {
|
||||
leftExpr = getExpr(left)
|
||||
reverse = false
|
||||
}
|
||||
if rightValue != nil {
|
||||
rightExpr = toValueExpr(rightValue)
|
||||
} else {
|
||||
rightExpr = getExpr(right)
|
||||
}
|
||||
|
||||
if leftExpr == nil || rightExpr == nil {
|
||||
return fmt.Errorf("invalid arithmetic expression, left: %s, op: %s, right: %s", ctx.Expr(0).GetText(), ctx.GetOp(), ctx.Expr(1).GetText())
|
||||
}
|
||||
|
||||
if !typeutil.IsArithmetic(leftExpr.dataType) || !typeutil.IsArithmetic(rightExpr.dataType) {
|
||||
return fmt.Errorf("'%s' can only be used between integer or floating expressions", arithNameMap[ctx.GetOp().GetTokenType()])
|
||||
}
|
||||
|
||||
switch ctx.GetOp().GetTokenType() {
|
||||
case parser.PlanParserMOD:
|
||||
if !typeutil.IsIntegerType(leftExpr.dataType) || !typeutil.IsIntegerType(rightExpr.dataType) {
|
||||
return fmt.Errorf("modulo can only apply on integer types")
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_BinaryArithExpr{
|
||||
BinaryArithExpr: &planpb.BinaryArithExpr{
|
||||
Left: leftExpr.expr,
|
||||
Right: rightExpr.expr,
|
||||
Op: arithExprMap[ctx.GetOp().GetTokenType()],
|
||||
},
|
||||
},
|
||||
}
|
||||
dataType, err := calcDataType(leftExpr, rightExpr, reverse)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: dataType,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitEquality translates expr to compare/range plan.
|
||||
func (v *ParserVisitor) VisitEquality(ctx *parser.EqualityContext) interface{} {
|
||||
left := ctx.Expr(0).Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
right := ctx.Expr(1).Accept(v)
|
||||
if err := getError(right); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftValue, rightValue := getGenericValue(left), getGenericValue(right)
|
||||
if leftValue != nil && rightValue != nil {
|
||||
switch ctx.GetOp().GetTokenType() {
|
||||
case parser.PlanParserEQ:
|
||||
return Equal(leftValue, rightValue)
|
||||
case parser.PlanParserNE:
|
||||
return NotEqual(leftValue, rightValue)
|
||||
default:
|
||||
return fmt.Errorf("unexpected op: %s", ctx.GetOp().GetText())
|
||||
}
|
||||
}
|
||||
|
||||
var leftExpr *ExprWithType
|
||||
var rightExpr *ExprWithType
|
||||
if leftValue != nil {
|
||||
leftExpr = toValueExpr(leftValue)
|
||||
} else {
|
||||
leftExpr = getExpr(left)
|
||||
}
|
||||
if rightValue != nil {
|
||||
rightExpr = toValueExpr(rightValue)
|
||||
} else {
|
||||
rightExpr = getExpr(right)
|
||||
}
|
||||
|
||||
expr, err := HandleCompare(ctx.GetOp().GetTokenType(), leftExpr, rightExpr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitRelational translates expr to range/compare plan.
|
||||
func (v *ParserVisitor) VisitRelational(ctx *parser.RelationalContext) interface{} {
|
||||
left := ctx.Expr(0).Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
right := ctx.Expr(1).Accept(v)
|
||||
if err := getError(right); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftValue, rightValue := getGenericValue(left), getGenericValue(right)
|
||||
if leftValue != nil && rightValue != nil {
|
||||
switch ctx.GetOp().GetTokenType() {
|
||||
case parser.PlanParserLT:
|
||||
return Less(leftValue, rightValue)
|
||||
case parser.PlanParserLE:
|
||||
return LessEqual(leftValue, rightValue)
|
||||
case parser.PlanParserGT:
|
||||
return Greater(leftValue, rightValue)
|
||||
case parser.PlanParserGE:
|
||||
return GreaterEqual(leftValue, rightValue)
|
||||
default:
|
||||
return fmt.Errorf("unexpected op: %s", ctx.GetOp().GetText())
|
||||
}
|
||||
}
|
||||
|
||||
var leftExpr *ExprWithType
|
||||
var rightExpr *ExprWithType
|
||||
if leftValue != nil {
|
||||
leftExpr = toValueExpr(leftValue)
|
||||
} else {
|
||||
leftExpr = getExpr(left)
|
||||
}
|
||||
if rightValue != nil {
|
||||
rightExpr = toValueExpr(rightValue)
|
||||
} else {
|
||||
rightExpr = getExpr(right)
|
||||
}
|
||||
|
||||
expr, err := HandleCompare(ctx.GetOp().GetTokenType(), leftExpr, rightExpr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitLike handles match operations.
|
||||
func (v *ParserVisitor) VisitLike(ctx *parser.LikeContext) interface{} {
|
||||
left := ctx.Expr().Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftExpr := getExpr(left)
|
||||
if leftExpr == nil {
|
||||
return fmt.Errorf("the left operand of like is invalid")
|
||||
}
|
||||
|
||||
if !typeutil.IsStringType(leftExpr.dataType) {
|
||||
return fmt.Errorf("like operation on non-text field is unsupported")
|
||||
}
|
||||
|
||||
column := toColumnInfo(leftExpr)
|
||||
if column == nil {
|
||||
return fmt.Errorf("like operation on complicated expr is unsupported")
|
||||
}
|
||||
|
||||
operand := NewString(ctx.StringLiteral().GetText())
|
||||
return &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_UnaryRangeExpr{
|
||||
UnaryRangeExpr: &planpb.UnaryRangeExpr{
|
||||
ColumnInfo: column,
|
||||
Op: planpb.OpType_Match,
|
||||
Value: operand,
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitTerm translates expr to term plan.
|
||||
func (v *ParserVisitor) VisitTerm(ctx *parser.TermContext) interface{} {
|
||||
child := ctx.Expr(0).Accept(v)
|
||||
if err := getError(child); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if childValue := getGenericValue(child); childValue != nil {
|
||||
return fmt.Errorf("'term' can only be used on non-const expression, but got: %s", ctx.Expr(0).GetText())
|
||||
}
|
||||
|
||||
childExpr := getExpr(child)
|
||||
columnInfo := toColumnInfo(childExpr)
|
||||
if columnInfo == nil {
|
||||
return fmt.Errorf("'term' can only be used on single field, but got: %s", ctx.Expr(0).GetText())
|
||||
}
|
||||
|
||||
allExpr := ctx.AllExpr()
|
||||
lenOfAllExpr := len(allExpr)
|
||||
values := make([]*planpb.GenericValue, 0, lenOfAllExpr)
|
||||
for i := 1; i < lenOfAllExpr; i++ {
|
||||
term := allExpr[i].Accept(v)
|
||||
if getError(term) != nil {
|
||||
return term
|
||||
}
|
||||
n := getGenericValue(term)
|
||||
if n == nil {
|
||||
return fmt.Errorf("value '%s' in list cannot be a non-const expression", ctx.Expr(i).GetText())
|
||||
}
|
||||
castedValue, err := castValue(childExpr.dataType, n)
|
||||
if err != nil {
|
||||
return fmt.Errorf("value '%s' in list cannot be casted to %s", ctx.Expr(i).GetText(), childExpr.dataType.String())
|
||||
}
|
||||
values = append(values, castedValue)
|
||||
}
|
||||
if len(values) <= 0 {
|
||||
return fmt.Errorf("'term' has empty value list")
|
||||
}
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_TermExpr{
|
||||
TermExpr: &planpb.TermExpr{
|
||||
ColumnInfo: columnInfo,
|
||||
Values: values,
|
||||
},
|
||||
},
|
||||
}
|
||||
if ctx.GetOp().GetTokenType() == parser.PlanParserNIN {
|
||||
expr = &planpb.Expr{
|
||||
Expr: &planpb.Expr_UnaryExpr{
|
||||
UnaryExpr: &planpb.UnaryExpr{
|
||||
Op: planpb.UnaryExpr_Not,
|
||||
Child: expr,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitEmptyTerm translates expr to term plan.
|
||||
func (v *ParserVisitor) VisitEmptyTerm(ctx *parser.EmptyTermContext) interface{} {
|
||||
child := ctx.Expr().Accept(v)
|
||||
if err := getError(child); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if childValue := getGenericValue(child); childValue != nil {
|
||||
return fmt.Errorf("'term' can only be used on non-const expression, but got: %s", ctx.Expr().GetText())
|
||||
}
|
||||
|
||||
childExpr := getExpr(child)
|
||||
columnInfo := toColumnInfo(childExpr)
|
||||
if columnInfo == nil {
|
||||
return fmt.Errorf("'term' can only be used on single field, but got: %s", ctx.Expr().GetText())
|
||||
}
|
||||
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_TermExpr{
|
||||
TermExpr: &planpb.TermExpr{
|
||||
ColumnInfo: columnInfo,
|
||||
Values: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
if ctx.GetOp().GetTokenType() == parser.PlanParserNIN {
|
||||
expr = &planpb.Expr{
|
||||
Expr: &planpb.Expr_UnaryExpr{
|
||||
UnaryExpr: &planpb.UnaryExpr{
|
||||
Op: planpb.UnaryExpr_Not,
|
||||
Child: expr,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitRange translates expr to range plan.
|
||||
func (v *ParserVisitor) VisitRange(ctx *parser.RangeContext) interface{} {
|
||||
child := ctx.Expr(1).Accept(v)
|
||||
if err := getError(child); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
childValue := getGenericValue(child)
|
||||
if childValue != nil {
|
||||
return fmt.Errorf("'range' can only be used on non-const expression")
|
||||
}
|
||||
|
||||
childExpr := getExpr(child)
|
||||
columnInfo := toColumnInfo(childExpr)
|
||||
if columnInfo == nil {
|
||||
return fmt.Errorf("range operations are only supported on single fields now, got: %s", ctx.Expr(1).GetText())
|
||||
}
|
||||
|
||||
lower := ctx.Expr(0).Accept(v)
|
||||
upper := ctx.Expr(2).Accept(v)
|
||||
if err := getError(lower); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := getError(upper); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lowerValue := getGenericValue(lower)
|
||||
upperValue := getGenericValue(upper)
|
||||
if lowerValue == nil {
|
||||
return fmt.Errorf("lowerbound cannot be a non-const expression: %s", ctx.Expr(0).GetText())
|
||||
}
|
||||
if upperValue == nil {
|
||||
return fmt.Errorf("upperbound cannot be a non-const expression: %s", ctx.Expr(1).GetText())
|
||||
}
|
||||
|
||||
switch childExpr.dataType {
|
||||
case schemapb.DataType_String, schemapb.DataType_VarChar:
|
||||
if !IsString(lowerValue) || !IsString(upperValue) {
|
||||
return fmt.Errorf("invalid range operations")
|
||||
}
|
||||
case schemapb.DataType_Bool:
|
||||
return fmt.Errorf("invalid range operations on boolean expr")
|
||||
case schemapb.DataType_Int8, schemapb.DataType_Int16, schemapb.DataType_Int32, schemapb.DataType_Int64:
|
||||
if !IsInteger(lowerValue) || !IsInteger(upperValue) {
|
||||
return fmt.Errorf("invalid range operations")
|
||||
}
|
||||
case schemapb.DataType_Float, schemapb.DataType_Double:
|
||||
if !IsNumber(lowerValue) || !IsNumber(upperValue) {
|
||||
return fmt.Errorf("invalid range operations")
|
||||
}
|
||||
if IsInteger(lowerValue) {
|
||||
lowerValue = NewFloat(float64(lowerValue.GetInt64Val()))
|
||||
}
|
||||
if IsInteger(upperValue) {
|
||||
upperValue = NewFloat(float64(upperValue.GetInt64Val()))
|
||||
}
|
||||
}
|
||||
|
||||
lowerInclusive := ctx.GetOp1().GetTokenType() == parser.PlanParserLE
|
||||
upperInclusive := ctx.GetOp2().GetTokenType() == parser.PlanParserLE
|
||||
|
||||
// if !(lowerInclusive && upperInclusive) {
|
||||
// if getGenericValue(GreaterEqual(lowerValue, upperValue)).GetBoolVal() {
|
||||
// return fmt.Errorf("invalid range: lowerbound is greater than upperbound")
|
||||
// }
|
||||
// } else {
|
||||
// if getGenericValue(Greater(lowerValue, upperValue)).GetBoolVal() {
|
||||
// return fmt.Errorf("invalid range: lowerbound is greater than upperbound")
|
||||
// }
|
||||
// }
|
||||
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_BinaryRangeExpr{
|
||||
BinaryRangeExpr: &planpb.BinaryRangeExpr{
|
||||
ColumnInfo: columnInfo,
|
||||
LowerInclusive: lowerInclusive,
|
||||
UpperInclusive: upperInclusive,
|
||||
LowerValue: lowerValue,
|
||||
UpperValue: upperValue,
|
||||
},
|
||||
},
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitReverseRange parses the expression like "1 > a > 0".
|
||||
func (v *ParserVisitor) VisitReverseRange(ctx *parser.ReverseRangeContext) interface{} {
|
||||
child := ctx.Expr(1).Accept(v)
|
||||
if err := getError(child); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
childValue := getGenericValue(child)
|
||||
if childValue != nil {
|
||||
return fmt.Errorf("'range' can only be used on non-const expression")
|
||||
}
|
||||
|
||||
childExpr := getExpr(child)
|
||||
columnInfo := toColumnInfo(childExpr)
|
||||
if columnInfo == nil {
|
||||
return fmt.Errorf("range operations are only supported on single fields now, got: %s", ctx.Expr(1).GetText())
|
||||
}
|
||||
|
||||
lower := ctx.Expr(2).Accept(v)
|
||||
upper := ctx.Expr(0).Accept(v)
|
||||
if err := getError(lower); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := getError(upper); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lowerValue := getGenericValue(lower)
|
||||
upperValue := getGenericValue(upper)
|
||||
if lowerValue == nil {
|
||||
return fmt.Errorf("lowerbound cannot be a non-const expression: %s", ctx.Expr(0).GetText())
|
||||
}
|
||||
if upperValue == nil {
|
||||
return fmt.Errorf("upperbound cannot be a non-const expression: %s", ctx.Expr(1).GetText())
|
||||
}
|
||||
|
||||
switch childExpr.dataType {
|
||||
case schemapb.DataType_String, schemapb.DataType_VarChar:
|
||||
if !IsString(lowerValue) || !IsString(upperValue) {
|
||||
return fmt.Errorf("invalid range operations")
|
||||
}
|
||||
case schemapb.DataType_Bool:
|
||||
return fmt.Errorf("invalid range operations on boolean expr")
|
||||
case schemapb.DataType_Int8, schemapb.DataType_Int16, schemapb.DataType_Int32, schemapb.DataType_Int64:
|
||||
if !IsInteger(lowerValue) || !IsInteger(upperValue) {
|
||||
return fmt.Errorf("invalid range operations")
|
||||
}
|
||||
case schemapb.DataType_Float, schemapb.DataType_Double:
|
||||
if !IsNumber(lowerValue) || !IsNumber(upperValue) {
|
||||
return fmt.Errorf("invalid range operations")
|
||||
}
|
||||
if IsInteger(lowerValue) {
|
||||
lowerValue = NewFloat(float64(lowerValue.GetInt64Val()))
|
||||
}
|
||||
if IsInteger(upperValue) {
|
||||
upperValue = NewFloat(float64(upperValue.GetInt64Val()))
|
||||
}
|
||||
}
|
||||
|
||||
lowerInclusive := ctx.GetOp2().GetTokenType() == parser.PlanParserGE
|
||||
upperInclusive := ctx.GetOp1().GetTokenType() == parser.PlanParserGE
|
||||
|
||||
// if !(lowerInclusive && upperInclusive) {
|
||||
// if getGenericValue(GreaterEqual(lowerValue, upperValue)).GetBoolVal() {
|
||||
// return fmt.Errorf("invalid range: lowerbound is greater than upperbound")
|
||||
// }
|
||||
// } else {
|
||||
// if getGenericValue(Greater(lowerValue, upperValue)).GetBoolVal() {
|
||||
// return fmt.Errorf("invalid range: lowerbound is greater than upperbound")
|
||||
// }
|
||||
// }
|
||||
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_BinaryRangeExpr{
|
||||
BinaryRangeExpr: &planpb.BinaryRangeExpr{
|
||||
ColumnInfo: columnInfo,
|
||||
LowerInclusive: lowerInclusive,
|
||||
UpperInclusive: upperInclusive,
|
||||
LowerValue: lowerValue,
|
||||
UpperValue: upperValue,
|
||||
},
|
||||
},
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitUnary unpack the +expr to expr.
|
||||
func (v *ParserVisitor) VisitUnary(ctx *parser.UnaryContext) interface{} {
|
||||
child := ctx.Expr().Accept(v)
|
||||
if err := getError(child); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
childValue := getGenericValue(child)
|
||||
if childValue != nil {
|
||||
switch ctx.GetOp().GetTokenType() {
|
||||
case parser.PlanParserADD:
|
||||
return child
|
||||
case parser.PlanParserSUB:
|
||||
return Negative(childValue)
|
||||
case parser.PlanParserNOT:
|
||||
return Not(childValue)
|
||||
default:
|
||||
return fmt.Errorf("unexpected op: %s", ctx.GetOp().GetText())
|
||||
}
|
||||
}
|
||||
|
||||
childExpr := getExpr(child)
|
||||
if childExpr == nil {
|
||||
return fmt.Errorf("failed to parse unary expressions")
|
||||
}
|
||||
switch ctx.GetOp().GetTokenType() {
|
||||
case parser.PlanParserADD:
|
||||
return childExpr
|
||||
case parser.PlanParserNOT:
|
||||
if !typeutil.IsBoolType(childExpr.dataType) {
|
||||
return fmt.Errorf("%s op can only be applied on boolean expression", unaryLogicalNameMap[parser.PlanParserNOT])
|
||||
}
|
||||
return &ExprWithType{
|
||||
expr: &planpb.Expr{
|
||||
Expr: &planpb.Expr_UnaryExpr{
|
||||
UnaryExpr: &planpb.UnaryExpr{
|
||||
Op: unaryLogicalOpMap[parser.PlanParserNOT],
|
||||
Child: childExpr.expr,
|
||||
},
|
||||
},
|
||||
},
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("unexpected op: %s", ctx.GetOp().GetText())
|
||||
}
|
||||
}
|
||||
|
||||
// VisitLogicalOr apply logical or to two boolean expressions.
|
||||
func (v *ParserVisitor) VisitLogicalOr(ctx *parser.LogicalOrContext) interface{} {
|
||||
left := ctx.Expr(0).Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
right := ctx.Expr(1).Accept(v)
|
||||
if err := getError(right); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftValue, rightValue := getGenericValue(left), getGenericValue(right)
|
||||
if leftValue != nil && rightValue != nil {
|
||||
n, err := Or(leftValue, rightValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
if leftValue != nil || rightValue != nil {
|
||||
return fmt.Errorf("'or' can only be used between boolean expressions")
|
||||
}
|
||||
|
||||
var leftExpr *ExprWithType
|
||||
var rightExpr *ExprWithType
|
||||
leftExpr = getExpr(left)
|
||||
rightExpr = getExpr(right)
|
||||
|
||||
if !typeutil.IsBoolType(leftExpr.dataType) || !typeutil.IsBoolType(rightExpr.dataType) {
|
||||
return fmt.Errorf("'or' can only be used between boolean expressions")
|
||||
}
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_BinaryExpr{
|
||||
BinaryExpr: &planpb.BinaryExpr{
|
||||
Left: leftExpr.expr,
|
||||
Right: rightExpr.expr,
|
||||
Op: planpb.BinaryExpr_LogicalOr,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitLogicalAnd apply logical and to two boolean expressions.
|
||||
func (v *ParserVisitor) VisitLogicalAnd(ctx *parser.LogicalAndContext) interface{} {
|
||||
left := ctx.Expr(0).Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
right := ctx.Expr(1).Accept(v)
|
||||
if err := getError(right); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftValue, rightValue := getGenericValue(left), getGenericValue(right)
|
||||
if leftValue != nil && rightValue != nil {
|
||||
n, err := And(leftValue, rightValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
if leftValue != nil || rightValue != nil {
|
||||
return fmt.Errorf("'and' can only be used between boolean expressions")
|
||||
}
|
||||
|
||||
var leftExpr *ExprWithType
|
||||
var rightExpr *ExprWithType
|
||||
leftExpr = getExpr(left)
|
||||
rightExpr = getExpr(right)
|
||||
|
||||
if !typeutil.IsBoolType(leftExpr.dataType) || !typeutil.IsBoolType(rightExpr.dataType) {
|
||||
return fmt.Errorf("'and' can only be used between boolean expressions")
|
||||
}
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_BinaryExpr{
|
||||
BinaryExpr: &planpb.BinaryExpr{
|
||||
Left: leftExpr.expr,
|
||||
Right: rightExpr.expr,
|
||||
Op: planpb.BinaryExpr_LogicalAnd,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
}
|
||||
|
||||
// VisitBitXor not supported.
|
||||
func (v *ParserVisitor) VisitBitXor(ctx *parser.BitXorContext) interface{} {
|
||||
return fmt.Errorf("BitXor is not supported: %s", ctx.GetText())
|
||||
}
|
||||
|
||||
// VisitBitAnd not supported.
|
||||
func (v *ParserVisitor) VisitBitAnd(ctx *parser.BitAndContext) interface{} {
|
||||
return fmt.Errorf("BitAnd is not supported: %s", ctx.GetText())
|
||||
}
|
||||
|
||||
// VisitPower parses power expression.
|
||||
func (v *ParserVisitor) VisitPower(ctx *parser.PowerContext) interface{} {
|
||||
left := ctx.Expr(0).Accept(v)
|
||||
if err := getError(left); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
right := ctx.Expr(1).Accept(v)
|
||||
if err := getError(right); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
leftValue, rightValue := getGenericValue(left), getGenericValue(right)
|
||||
if leftValue != nil && rightValue != nil {
|
||||
return Power(leftValue, rightValue)
|
||||
}
|
||||
|
||||
return fmt.Errorf("power can only apply on constants: %s", ctx.GetText())
|
||||
}
|
||||
|
||||
// VisitShift unsupported.
|
||||
func (v *ParserVisitor) VisitShift(ctx *parser.ShiftContext) interface{} {
|
||||
return fmt.Errorf("shift is not supported: %s", ctx.GetText())
|
||||
}
|
||||
|
||||
// VisitBitOr unsupported.
|
||||
func (v *ParserVisitor) VisitBitOr(ctx *parser.BitOrContext) interface{} {
|
||||
return fmt.Errorf("BitOr is not supported: %s", ctx.GetText())
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
)
|
||||
|
||||
func handleExpr(schema *typeutil.SchemaHelper, exprStr string) interface{} {
|
||||
if exprStr == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
inputStream := antlr.NewInputStream(exprStr)
|
||||
errorListener := &errorListener{}
|
||||
parser := getParser(inputStream, errorListener)
|
||||
|
||||
ast := parser.Expr()
|
||||
if errorListener.err != nil {
|
||||
return errorListener.err
|
||||
}
|
||||
|
||||
visitor := NewParserVisitor(schema)
|
||||
return ast.Accept(visitor)
|
||||
}
|
||||
|
||||
func ParseExpr(schema *typeutil.SchemaHelper, exprStr string) (*planpb.Expr, error) {
|
||||
if len(exprStr) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
ret := handleExpr(schema, exprStr)
|
||||
|
||||
if err := getError(ret); err != nil {
|
||||
return nil, fmt.Errorf("cannot parse expression: %s, error: %s", exprStr, err)
|
||||
}
|
||||
|
||||
predicate := getExpr(ret)
|
||||
if predicate == nil {
|
||||
return nil, fmt.Errorf("cannot parse expression: %s", exprStr)
|
||||
}
|
||||
|
||||
if !typeutil.IsBoolType(predicate.dataType) {
|
||||
return nil, fmt.Errorf("predicate is not a boolean expression: %s, data type: %s", exprStr, predicate.dataType)
|
||||
}
|
||||
|
||||
return predicate.expr, nil
|
||||
}
|
||||
|
||||
func CreateRetrievePlan(schemaPb *schemapb.CollectionSchema, exprStr string) (*planpb.PlanNode, error) {
|
||||
schema, err := typeutil.CreateSchemaHelper(schemaPb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expr, err := ParseExpr(schema, exprStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
planNode := &planpb.PlanNode{
|
||||
Node: &planpb.PlanNode_Predicates{
|
||||
Predicates: expr,
|
||||
},
|
||||
}
|
||||
return planNode, nil
|
||||
}
|
||||
|
||||
func CreateSearchPlan(schemaPb *schemapb.CollectionSchema, exprStr string, vectorFieldName string, queryInfo *planpb.QueryInfo) (*planpb.PlanNode, error) {
|
||||
schema, err := typeutil.CreateSchemaHelper(schemaPb)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expr, err := ParseExpr(schema, exprStr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vectorField, err := schema.GetFieldFromName(vectorFieldName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fieldID := vectorField.FieldID
|
||||
dataType := vectorField.DataType
|
||||
|
||||
if !typeutil.IsVectorType(dataType) {
|
||||
return nil, fmt.Errorf("field (%s) to search is not of vector data type", vectorFieldName)
|
||||
}
|
||||
|
||||
planNode := &planpb.PlanNode{
|
||||
Node: &planpb.PlanNode_VectorAnns{
|
||||
VectorAnns: &planpb.VectorANNS{
|
||||
IsBinary: dataType == schemapb.DataType_BinaryVector,
|
||||
Predicates: expr,
|
||||
QueryInfo: queryInfo,
|
||||
PlaceholderTag: "$0",
|
||||
FieldId: fieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
return planNode, nil
|
||||
}
|
|
@ -0,0 +1,479 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
)
|
||||
|
||||
func newTestSchema() *schemapb.CollectionSchema {
|
||||
fields := []*schemapb.FieldSchema{
|
||||
{FieldID: 0, Name: "FieldID", IsPrimaryKey: false, Description: "field no.1", DataType: schemapb.DataType_Int64},
|
||||
}
|
||||
|
||||
for name, value := range schemapb.DataType_value {
|
||||
dataType := schemapb.DataType(value)
|
||||
newField := &schemapb.FieldSchema{
|
||||
FieldID: int64(100 + value), Name: name + "Field", IsPrimaryKey: false, Description: "", DataType: dataType,
|
||||
}
|
||||
fields = append(fields, newField)
|
||||
}
|
||||
|
||||
return &schemapb.CollectionSchema{
|
||||
Name: "test",
|
||||
Description: "schema for test used",
|
||||
AutoID: true,
|
||||
Fields: fields,
|
||||
}
|
||||
}
|
||||
|
||||
func assertValidExpr(t *testing.T, helper *typeutil.SchemaHelper, exprStr string) {
|
||||
_, err := ParseExpr(helper, exprStr)
|
||||
assert.NoError(t, err, exprStr)
|
||||
|
||||
// expr, err := ParseExpr(helper, exprStr)
|
||||
// assert.NoError(t, err, exprStr)
|
||||
// fmt.Printf("expr: %s\n", exprStr)
|
||||
// ShowExpr(expr)
|
||||
}
|
||||
|
||||
func assertInvalidExpr(t *testing.T, helper *typeutil.SchemaHelper, exprStr string) {
|
||||
_, err := ParseExpr(helper, exprStr)
|
||||
assert.Error(t, err, exprStr)
|
||||
}
|
||||
|
||||
func TestExpr_Term(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`BoolField in [true, false]`,
|
||||
`Int8Field in [1, 2]`,
|
||||
`Int16Field in [3, 4]`,
|
||||
`Int32Field in [5, 6]`,
|
||||
`Int64Field in [7, 8]`,
|
||||
`FloatField in [9.0, 10.0]`,
|
||||
`DoubleField in [11.0, 12.0]`,
|
||||
`StringField in ["str13", "str14"]`,
|
||||
`VarCharField in ["str15", "str16"]`,
|
||||
`FloatField in [1373, 115]`,
|
||||
`Int64Field in []`,
|
||||
`Int64Field not in []`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_Compare(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`Int8Field < Int16Field`,
|
||||
`Int16Field <= Int32Field`,
|
||||
`Int32Field > Int64Field`,
|
||||
`Int64Field >= FloatField`,
|
||||
`FloatField == DoubleField`,
|
||||
`StringField != VarCharField`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_UnaryRange(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`Int8Field < 0`,
|
||||
`Int16Field <= 1`,
|
||||
`Int32Field > 2`,
|
||||
`Int64Field >= 3`,
|
||||
`FloatField == 4.0`,
|
||||
`FloatField == 2`,
|
||||
`DoubleField != 5.0`,
|
||||
`StringField > "str6"`,
|
||||
`VarCharField <= "str7"`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_Like(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`VarCharField like "prefix%"`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_BinaryRange(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`1 < Int8Field < 2`,
|
||||
`3 <= Int16Field < 4`,
|
||||
`5 <= Int32Field <= 6`,
|
||||
`7 < Int64Field <= 8`,
|
||||
`9.0 < FloatField < 10.0`,
|
||||
`11.0 < DoubleField < 12.0`,
|
||||
`"str13" < StringField < "str14"`,
|
||||
`"str15" < VarCharField < "str16"`,
|
||||
`17 < DoubleField < 18`,
|
||||
|
||||
`2 > Int8Field > 1`,
|
||||
`4 >= Int16Field >= 3`,
|
||||
`6 >= Int32Field >= 5`,
|
||||
`8 >= Int64Field > 7`,
|
||||
`10.0 > FloatField > 9.0`,
|
||||
`12.0 > DoubleField > 11.0`,
|
||||
`"str14" > StringField > "str13"`,
|
||||
`"str16" > VarCharField > "str15"`,
|
||||
`18 > DoubleField > 17`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_BinaryArith(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`Int64Field % 10 == 9`,
|
||||
`Int64Field % 10 != 9`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
}
|
||||
|
||||
// TODO: enable these after execution backend is ready.
|
||||
unsupported := []string{
|
||||
`Int8Field + 1 < 2`,
|
||||
`Int16Field - 3 <= 4`,
|
||||
`Int32Field * 5 > 6`,
|
||||
`Int64Field / 7 >= 8`,
|
||||
`FloatField + 11 < 12`,
|
||||
`DoubleField - 13 < 14`,
|
||||
}
|
||||
for _, exprStr := range unsupported {
|
||||
assertInvalidExpr(t, helper, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_Value(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`1`,
|
||||
`2.0`,
|
||||
`true`,
|
||||
`false`,
|
||||
`"str"`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
expr := handleExpr(helper, exprStr)
|
||||
assert.NotNil(t, getExpr(expr).expr, exprStr)
|
||||
// fmt.Printf("expr: %s\n", exprStr)
|
||||
// ShowExpr(getExpr(expr).expr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_Identifier(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`BoolField`,
|
||||
`Int8Field`,
|
||||
`Int16Field`,
|
||||
`Int32Field`,
|
||||
`Int64Field`,
|
||||
`FloatField`,
|
||||
`DoubleField`,
|
||||
`StringField`,
|
||||
`VarCharField`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
expr := handleExpr(helper, exprStr)
|
||||
assert.NotNil(t, getExpr(expr).expr, exprStr)
|
||||
|
||||
// fmt.Printf("expr: %s\n", exprStr)
|
||||
// ShowExpr(getExpr(expr).expr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_Constant(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
// ------------------- arithmetic operations ----------------
|
||||
`1.0 + 2.0`,
|
||||
`1.0 + 2`,
|
||||
`1 + 2.0`,
|
||||
`1 + 2`,
|
||||
`1.0 - 2.0`,
|
||||
`1.0 - 2`,
|
||||
`1 - 2.0`,
|
||||
`1 - 2`,
|
||||
`1.0 * 2.0`,
|
||||
`1.0 * 2`,
|
||||
`1 * 2.0`,
|
||||
`1 * 2`,
|
||||
`1.0 / 2.0`,
|
||||
`1.0 / 2`,
|
||||
`1 / 2.0`,
|
||||
`1 / 2`,
|
||||
`1 % 2`,
|
||||
// ------------------- logical operations ----------------
|
||||
`true and false`,
|
||||
`true or false`,
|
||||
`!true`,
|
||||
`!false`,
|
||||
// ------------------- relational operations ----------------
|
||||
`"1" < "2"`,
|
||||
`1.0 < 2.0`,
|
||||
`1.0 < 2`,
|
||||
`1 < 2.0`,
|
||||
`1 < 2`,
|
||||
`"1" <= "2"`,
|
||||
`1.0 <= 2.0`,
|
||||
`1.0 <= 2`,
|
||||
`1 <= 2.0`,
|
||||
`1 <= 2`,
|
||||
`"1" > "2"`,
|
||||
`1.0 > 2.0`,
|
||||
`1.0 > 2`,
|
||||
`1 > 2.0`,
|
||||
`1 > 2`,
|
||||
`"1" >= "2"`,
|
||||
`1.0 >= 2.0`,
|
||||
`1.0 >= 2`,
|
||||
`1 >= 2.0`,
|
||||
`1 >= 2`,
|
||||
`"1" == "2"`,
|
||||
`1.0 == 2.0`,
|
||||
`1.0 == 2`,
|
||||
`1 == 2.0`,
|
||||
`1 == 2`,
|
||||
`true == false`,
|
||||
`"1" != "2"`,
|
||||
`1.0 != 2.0`,
|
||||
`1.0 != 2`,
|
||||
`1 != 2.0`,
|
||||
`1 != 2`,
|
||||
`true != false`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
expr := handleExpr(helper, exprStr)
|
||||
assert.NotNil(t, getExpr(expr).expr, exprStr)
|
||||
|
||||
// fmt.Printf("expr: %s\n", exprStr)
|
||||
// ShowExpr(getExpr(expr).expr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpr_Combinations(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`not (Int8Field + 1 == 2)`,
|
||||
`(Int16Field - 3 == 4) and (Int32Field * 5 != 6)`,
|
||||
`(Int64Field / 7 != 8) or (Int64Field % 10 == 9)`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExpr(t, helper, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateRetrievePlan(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
_, err := CreateRetrievePlan(schema, "Int64Field > 0")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestCreateSearchPlan(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
_, err := CreateSearchPlan(schema, "Int64Field > 0", "FloatVectorField", &planpb.QueryInfo{
|
||||
Topk: 0,
|
||||
MetricType: "",
|
||||
SearchParams: "",
|
||||
RoundDecimal: 0,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestExpr_Invalid(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
exprStrs := []string{
|
||||
`invalid expression`,
|
||||
`"constant"`,
|
||||
// -------------- identifier not in schema --------------
|
||||
`not_in_schema`,
|
||||
// ------------------------ Add/Sub ---------------------
|
||||
`not_in_schema + 1`,
|
||||
`1 - not_in_schema`,
|
||||
`true + false`,
|
||||
`"str" + "text"`,
|
||||
`true + "str"`,
|
||||
`true - false`,
|
||||
`"str" - "text"`,
|
||||
`true - "str"`,
|
||||
`StringField + VarCharField`,
|
||||
`StringField - 2`,
|
||||
`2 + StringField`,
|
||||
// ------------------------ Mul/Div/Mod ---------------------
|
||||
`not_in_schema * 1`,
|
||||
`1 / not_in_schema`,
|
||||
`1 % not_in_schema`,
|
||||
`true * false`,
|
||||
`true / false`,
|
||||
`true % false`,
|
||||
`"str" * "text"`,
|
||||
`"str" / "text"`,
|
||||
`"str" % "text"`,
|
||||
`2 / 0`,
|
||||
`2 % 0`,
|
||||
`StringField % VarCharField`,
|
||||
`StringField * 2`,
|
||||
`2 / StringField`,
|
||||
// ----------------------- ==/!= -------------------------
|
||||
`not_in_schema != 1`,
|
||||
`1 == not_in_schema`,
|
||||
`true == "str"`,
|
||||
`"str" != false`,
|
||||
// ---------------------- relational --------------------
|
||||
`not_in_schema < 1`,
|
||||
`1 <= not_in_schema`,
|
||||
`true <= "str"`,
|
||||
`"str" >= false`,
|
||||
// ------------------------ like ------------------------
|
||||
`(VarCharField % 2) like "prefix%"`,
|
||||
`FloatField like "prefix%"`,
|
||||
`value like "prefix%"`,
|
||||
// ------------------------ term ------------------------
|
||||
`not_in_schema in [1, 2, 3]`,
|
||||
`1 in [1, 2, 3]`,
|
||||
`(Int8Field + 8) in [1, 2, 3]`,
|
||||
`Int8Field in [(true + 1)]`,
|
||||
`Int8Field in [Int16Field]`,
|
||||
`BoolField in [4.0]`,
|
||||
`VarCharField in [4.0]`,
|
||||
`Int32Field in [4.0]`,
|
||||
`FloatField in [5, 6.0, true]`,
|
||||
// ----------------------- range -------------------------
|
||||
`1 < not_in_schema < 2`,
|
||||
`1 < 3 < 2`,
|
||||
`1 < (Int8Field + Int16Field) < 2`,
|
||||
`(invalid_lower) < Int32Field < 2`,
|
||||
`1 < Int32Field < (invalid_upper)`,
|
||||
`(Int8Field) < Int32Field < 2`,
|
||||
`1 < Int32Field < (Int16Field)`,
|
||||
`1 < StringField < 2`,
|
||||
`1 < BoolField < 2`,
|
||||
`1.0 < Int32Field < 2.0`,
|
||||
`true < FloatField < false`,
|
||||
// `2 <= Int32Field <= 1`,
|
||||
`2 = Int32Field = 1`,
|
||||
`true = BoolField = false`,
|
||||
// ----------------------- unary ------------------------
|
||||
`-true`,
|
||||
`!"str"`,
|
||||
`!(not_in_schema)`,
|
||||
`-Int32Field`,
|
||||
`!(Int32Field)`,
|
||||
// ----------------------- or/and ------------------------
|
||||
`not_in_schema or true`,
|
||||
`false or not_in_schema`,
|
||||
`"str" or false`,
|
||||
`BoolField or false`,
|
||||
`Int32Field or Int64Field`,
|
||||
`not_in_schema and true`,
|
||||
`false and not_in_schema`,
|
||||
`"str" and false`,
|
||||
`BoolField and false`,
|
||||
`Int32Field and Int64Field`,
|
||||
// -------------------- unsupported ----------------------
|
||||
`1 ^ 2`,
|
||||
`1 & 2`,
|
||||
`1 ** 2`,
|
||||
`1 << 2`,
|
||||
`1 | 2`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
_, err := ParseExpr(helper, exprStr)
|
||||
assert.Error(t, err, exprStr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateRetrievePlan_Invalid(t *testing.T) {
|
||||
t.Run("invalid schema", func(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
schema.Fields = append(schema.Fields, schema.Fields[0])
|
||||
_, err := CreateRetrievePlan(schema, "")
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("invalid expr", func(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
_, err := CreateRetrievePlan(schema, "invalid expression")
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCreateSearchPlan_Invalid(t *testing.T) {
|
||||
t.Run("invalid schema", func(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
schema.Fields = append(schema.Fields, schema.Fields[0])
|
||||
_, err := CreateSearchPlan(schema, "", "", nil)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("invalid expr", func(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
_, err := CreateSearchPlan(schema, "invalid expression", "", nil)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("invalid vector field", func(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
_, err := CreateSearchPlan(schema, "Int64Field > 0", "not_exist", nil)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("not vector type", func(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
_, err := CreateSearchPlan(schema, "Int64Field > 0", "VarCharField", nil)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
antlrparser "github.com/milvus-io/milvus/internal/parser/planparserv2/generated"
|
||||
)
|
||||
|
||||
var (
|
||||
lexerPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return antlrparser.NewPlanLexer(nil)
|
||||
},
|
||||
}
|
||||
parserPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return antlrparser.NewPlanParser(nil)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func getLexer(stream *antlr.InputStream, listeners ...antlr.ErrorListener) *antlrparser.PlanLexer {
|
||||
lexer, ok := lexerPool.Get().(*antlrparser.PlanLexer)
|
||||
if !ok {
|
||||
lexer = antlrparser.NewPlanLexer(nil)
|
||||
}
|
||||
lexer.SetInputStream(stream)
|
||||
for _, listener := range listeners {
|
||||
lexer.AddErrorListener(listener)
|
||||
}
|
||||
lexerPool.Put(lexer)
|
||||
return lexer
|
||||
}
|
||||
|
||||
func getParser(stream *antlr.InputStream, listeners ...antlr.ErrorListener) *antlrparser.PlanParser {
|
||||
lexer := getLexer(stream, listeners...)
|
||||
tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
|
||||
parser, ok := parserPool.Get().(*antlrparser.PlanParser)
|
||||
if !ok {
|
||||
parser = antlrparser.NewPlanParser(nil)
|
||||
}
|
||||
parser.SetInputStream(tokenStream)
|
||||
parser.BuildParseTrees = true
|
||||
for _, listener := range listeners {
|
||||
parser.AddErrorListener(listener)
|
||||
}
|
||||
parserPool.Put(parser)
|
||||
return parser
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||
|
||||
antlrparser "github.com/milvus-io/milvus/internal/parser/planparserv2/generated"
|
||||
)
|
||||
|
||||
func genNaiveInputStream() *antlr.InputStream {
|
||||
return antlr.NewInputStream("a > 2")
|
||||
}
|
||||
|
||||
func Test_getLexer(t *testing.T) {
|
||||
var lexer *antlrparser.PlanLexer
|
||||
|
||||
lexer = getLexer(genNaiveInputStream(), &errorListener{})
|
||||
assert.NotNil(t, lexer)
|
||||
|
||||
lexer = getLexer(genNaiveInputStream(), &errorListener{})
|
||||
assert.NotNil(t, lexer)
|
||||
}
|
||||
|
||||
func Test_getParser(t *testing.T) {
|
||||
var parser *antlrparser.PlanParser
|
||||
|
||||
parser = getParser(genNaiveInputStream(), &errorListener{})
|
||||
assert.NotNil(t, parser)
|
||||
|
||||
parser = getParser(genNaiveInputStream(), &errorListener{})
|
||||
assert.NotNil(t, parser)
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
)
|
||||
|
||||
type ShowExprVisitor struct {
|
||||
}
|
||||
|
||||
func extractColumnInfo(info *planpb.ColumnInfo) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["field_id"] = info.GetFieldId()
|
||||
js["data_type"] = info.GetDataType().String()
|
||||
js["auto_id"] = info.GetIsAutoID()
|
||||
js["is_pk"] = info.GetIsPrimaryKey()
|
||||
return js
|
||||
}
|
||||
|
||||
func extractGenericValue(value *planpb.GenericValue) interface{} {
|
||||
switch realValue := value.Val.(type) {
|
||||
case *planpb.GenericValue_BoolVal:
|
||||
return realValue.BoolVal
|
||||
case *planpb.GenericValue_Int64Val:
|
||||
return realValue.Int64Val
|
||||
case *planpb.GenericValue_FloatVal:
|
||||
// // floating point value is not convenient to compare.
|
||||
// return strconv.FormatFloat(realValue.FloatVal, 'g', 10, 64)
|
||||
return realValue.FloatVal
|
||||
case *planpb.GenericValue_StringVal:
|
||||
return realValue.StringVal
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitExpr(expr *planpb.Expr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
switch realExpr := expr.Expr.(type) {
|
||||
case *planpb.Expr_TermExpr:
|
||||
js["expr"] = v.VisitTermExpr(realExpr.TermExpr)
|
||||
case *planpb.Expr_UnaryExpr:
|
||||
js["expr"] = v.VisitUnaryExpr(realExpr.UnaryExpr)
|
||||
case *planpb.Expr_BinaryExpr:
|
||||
js["expr"] = v.VisitBinaryExpr(realExpr.BinaryExpr)
|
||||
case *planpb.Expr_CompareExpr:
|
||||
js["expr"] = v.VisitCompareExpr(realExpr.CompareExpr)
|
||||
case *planpb.Expr_UnaryRangeExpr:
|
||||
js["expr"] = v.VisitUnaryRangeExpr(realExpr.UnaryRangeExpr)
|
||||
case *planpb.Expr_BinaryRangeExpr:
|
||||
js["expr"] = v.VisitBinaryRangeExpr(realExpr.BinaryRangeExpr)
|
||||
case *planpb.Expr_BinaryArithOpEvalRangeExpr:
|
||||
js["expr"] = v.VisitBinaryArithOpEvalRangeExpr(realExpr.BinaryArithOpEvalRangeExpr)
|
||||
case *planpb.Expr_BinaryArithExpr:
|
||||
js["expr"] = v.VisitBinaryArithExpr(realExpr.BinaryArithExpr)
|
||||
case *planpb.Expr_ValueExpr:
|
||||
js["expr"] = v.VisitValueExpr(realExpr.ValueExpr)
|
||||
case *planpb.Expr_ColumnExpr:
|
||||
js["expr"] = v.VisitColumnExpr(realExpr.ColumnExpr)
|
||||
default:
|
||||
js["expr"] = ""
|
||||
}
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitTermExpr(expr *planpb.TermExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "term"
|
||||
js["column_info"] = extractColumnInfo(expr.ColumnInfo)
|
||||
terms := make([]interface{}, 0, len(expr.Values))
|
||||
for _, v := range expr.Values {
|
||||
terms = append(terms, extractGenericValue(v))
|
||||
}
|
||||
js["terms"] = terms
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitUnaryExpr(expr *planpb.UnaryExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = expr.Op.String()
|
||||
js["child"] = v.VisitExpr(expr.Child)
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitBinaryExpr(expr *planpb.BinaryExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = expr.Op.String()
|
||||
js["left_child"] = v.VisitExpr(expr.Left)
|
||||
js["right_child"] = v.VisitExpr(expr.Right)
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitCompareExpr(expr *planpb.CompareExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "compare"
|
||||
js["op"] = expr.Op.String()
|
||||
js["left_column_info"] = extractColumnInfo(expr.LeftColumnInfo)
|
||||
js["right_column_info"] = extractColumnInfo(expr.RightColumnInfo)
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitUnaryRangeExpr(expr *planpb.UnaryRangeExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "unary_range"
|
||||
js["op"] = expr.Op.String()
|
||||
js["column_info"] = extractColumnInfo(expr.GetColumnInfo())
|
||||
js["operand"] = extractGenericValue(expr.Value)
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitBinaryRangeExpr(expr *planpb.BinaryRangeExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "binary_range"
|
||||
js["column_info"] = extractColumnInfo(expr.GetColumnInfo())
|
||||
js["lower_value"] = extractGenericValue(expr.GetLowerValue())
|
||||
js["upper_value"] = extractGenericValue(expr.GetUpperValue())
|
||||
js["lower_inclusive"] = expr.GetLowerInclusive()
|
||||
js["upper_inclusive"] = expr.GetUpperInclusive()
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitBinaryArithOpEvalRangeExpr(expr *planpb.BinaryArithOpEvalRangeExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "binary_arith_op_eval_range"
|
||||
js["column_info"] = extractColumnInfo(expr.ColumnInfo)
|
||||
js["arith_op"] = expr.ArithOp.String()
|
||||
js["right_operand"] = extractGenericValue(expr.GetRightOperand())
|
||||
js["op"] = expr.Op.String()
|
||||
js["value"] = extractGenericValue(expr.GetValue())
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitBinaryArithExpr(expr *planpb.BinaryArithExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "binary_arith"
|
||||
js["left_expr"] = v.VisitExpr(expr.GetLeft())
|
||||
js["right_expr"] = v.VisitExpr(expr.GetRight())
|
||||
js["op"] = expr.Op.String()
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitValueExpr(expr *planpb.ValueExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "value_expr"
|
||||
js["value"] = extractGenericValue(expr.GetValue())
|
||||
return js
|
||||
}
|
||||
|
||||
func (v *ShowExprVisitor) VisitColumnExpr(expr *planpb.ColumnExpr) interface{} {
|
||||
js := make(map[string]interface{})
|
||||
js["expr_type"] = "column"
|
||||
js["column_info"] = extractColumnInfo(expr.GetInfo())
|
||||
return js
|
||||
}
|
||||
|
||||
func NewShowExprVisitor() LogicalExprVisitor {
|
||||
return &ShowExprVisitor{}
|
||||
}
|
||||
|
||||
// ShowExpr print the expr tree, used for debugging, not safe.
|
||||
func ShowExpr(expr *planpb.Expr) {
|
||||
v := NewShowExprVisitor()
|
||||
js := v.VisitExpr(expr)
|
||||
b, _ := json.MarshalIndent(js, "", " ")
|
||||
fmt.Println(string(b))
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
package planparserv2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/util/typeutil"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/proto/planpb"
|
||||
"github.com/milvus-io/milvus/internal/proto/schemapb"
|
||||
)
|
||||
|
||||
func IsBool(n *planpb.GenericValue) bool {
|
||||
switch n.GetVal().(type) {
|
||||
case *planpb.GenericValue_BoolVal:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsInteger(n *planpb.GenericValue) bool {
|
||||
switch n.GetVal().(type) {
|
||||
case *planpb.GenericValue_Int64Val:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsFloating(n *planpb.GenericValue) bool {
|
||||
switch n.GetVal().(type) {
|
||||
case *planpb.GenericValue_FloatVal:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsNumber(n *planpb.GenericValue) bool {
|
||||
return IsInteger(n) || IsFloating(n)
|
||||
}
|
||||
|
||||
func IsString(n *planpb.GenericValue) bool {
|
||||
switch n.GetVal().(type) {
|
||||
case *planpb.GenericValue_StringVal:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func NewBool(value bool) *planpb.GenericValue {
|
||||
return &planpb.GenericValue{
|
||||
Val: &planpb.GenericValue_BoolVal{
|
||||
BoolVal: value,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewInt(value int64) *planpb.GenericValue {
|
||||
return &planpb.GenericValue{
|
||||
Val: &planpb.GenericValue_Int64Val{
|
||||
Int64Val: value,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewFloat(value float64) *planpb.GenericValue {
|
||||
return &planpb.GenericValue{
|
||||
Val: &planpb.GenericValue_FloatVal{
|
||||
FloatVal: value,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewString(value string) *planpb.GenericValue {
|
||||
return &planpb.GenericValue{
|
||||
Val: &planpb.GenericValue_StringVal{
|
||||
StringVal: value,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func toValueExpr(n *planpb.GenericValue) *ExprWithType {
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_ValueExpr{
|
||||
ValueExpr: &planpb.ValueExpr{
|
||||
Value: n,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
switch n.GetVal().(type) {
|
||||
case *planpb.GenericValue_BoolVal:
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Bool,
|
||||
}
|
||||
case *planpb.GenericValue_Int64Val:
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Int64,
|
||||
}
|
||||
case *planpb.GenericValue_FloatVal:
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_Double,
|
||||
}
|
||||
case *planpb.GenericValue_StringVal:
|
||||
return &ExprWithType{
|
||||
expr: expr,
|
||||
dataType: schemapb.DataType_VarChar,
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func getSameType(a, b schemapb.DataType) (schemapb.DataType, error) {
|
||||
if typeutil.IsFloatingType(a) && typeutil.IsArithmetic(b) {
|
||||
return schemapb.DataType_Double, nil
|
||||
}
|
||||
|
||||
if typeutil.IsIntegerType(a) && typeutil.IsIntegerType(b) {
|
||||
return schemapb.DataType_Int64, nil
|
||||
}
|
||||
|
||||
return schemapb.DataType_None, fmt.Errorf("incompatible data type, %s, %s", a.String(), b.String())
|
||||
}
|
||||
|
||||
func calcDataType(left, right *ExprWithType, reverse bool) (schemapb.DataType, error) {
|
||||
if reverse {
|
||||
return getSameType(right.dataType, left.dataType)
|
||||
}
|
||||
return getSameType(left.dataType, right.dataType)
|
||||
}
|
||||
|
||||
func reverseOrder(op planpb.OpType) (planpb.OpType, error) {
|
||||
switch op {
|
||||
case planpb.OpType_LessThan:
|
||||
return planpb.OpType_GreaterThan, nil
|
||||
case planpb.OpType_LessEqual:
|
||||
return planpb.OpType_GreaterEqual, nil
|
||||
case planpb.OpType_GreaterThan:
|
||||
return planpb.OpType_LessThan, nil
|
||||
case planpb.OpType_GreaterEqual:
|
||||
return planpb.OpType_LessEqual, nil
|
||||
case planpb.OpType_Equal:
|
||||
return planpb.OpType_Equal, nil
|
||||
case planpb.OpType_NotEqual:
|
||||
return planpb.OpType_NotEqual, nil
|
||||
default:
|
||||
return planpb.OpType_Invalid, fmt.Errorf("cannot reverse order: %s", op)
|
||||
}
|
||||
}
|
||||
|
||||
func toColumnInfo(left *ExprWithType) *planpb.ColumnInfo {
|
||||
return left.expr.GetColumnExpr().GetInfo()
|
||||
}
|
||||
|
||||
func castValue(dataType schemapb.DataType, value *planpb.GenericValue) (*planpb.GenericValue, error) {
|
||||
if typeutil.IsStringType(dataType) && IsString(value) {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
if typeutil.IsBoolType(dataType) && IsBool(value) {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
if typeutil.IsFloatingType(dataType) {
|
||||
if IsFloating(value) {
|
||||
return value, nil
|
||||
}
|
||||
if IsInteger(value) {
|
||||
return NewFloat(float64(value.GetInt64Val())), nil
|
||||
}
|
||||
}
|
||||
|
||||
if typeutil.IsIntegerType(dataType) {
|
||||
if IsInteger(value) {
|
||||
return value, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("cannot cast value to %s, value: %s", dataType.String(), value)
|
||||
}
|
||||
|
||||
func combineBinaryArithExpr(op planpb.OpType, arithOp planpb.ArithOpType, columnInfo *planpb.ColumnInfo, operand *planpb.GenericValue, value *planpb.GenericValue) *planpb.Expr {
|
||||
castedValue, err := castValue(columnInfo.GetDataType(), operand)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return &planpb.Expr{
|
||||
Expr: &planpb.Expr_BinaryArithOpEvalRangeExpr{
|
||||
BinaryArithOpEvalRangeExpr: &planpb.BinaryArithOpEvalRangeExpr{
|
||||
ColumnInfo: columnInfo,
|
||||
ArithOp: arithOp,
|
||||
RightOperand: castedValue,
|
||||
Op: op,
|
||||
Value: value,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func handleBinaryArithExpr(op planpb.OpType, arithExpr *planpb.BinaryArithExpr, valueExpr *planpb.ValueExpr) (*planpb.Expr, error) {
|
||||
switch op {
|
||||
case planpb.OpType_Equal, planpb.OpType_NotEqual:
|
||||
break
|
||||
default:
|
||||
// TODO: enable this after execution is ready.
|
||||
return nil, fmt.Errorf("%s is not supported in execution backend", op)
|
||||
}
|
||||
|
||||
leftExpr, leftValue := arithExpr.Left.GetColumnExpr(), arithExpr.Left.GetValueExpr()
|
||||
rightExpr, rightValue := arithExpr.Right.GetColumnExpr(), arithExpr.Right.GetValueExpr()
|
||||
|
||||
if leftExpr != nil && rightExpr != nil {
|
||||
// a + b == 3
|
||||
return nil, fmt.Errorf("not supported to do arithmetic operations between multiple fields")
|
||||
}
|
||||
|
||||
if leftValue != nil && rightValue != nil {
|
||||
// 2 + 1 == 3
|
||||
return nil, fmt.Errorf("unexpected, should be optimized already")
|
||||
}
|
||||
|
||||
if leftExpr != nil && rightValue != nil {
|
||||
// a + 2 == 3
|
||||
// a - 2 == 3
|
||||
// a * 2 == 3
|
||||
// a / 2 == 3
|
||||
// a % 2 == 3
|
||||
return combineBinaryArithExpr(op, arithExpr.GetOp(), leftExpr.GetInfo(), rightValue.GetValue(), valueExpr.GetValue()), nil
|
||||
} else if rightExpr != nil && leftValue != nil {
|
||||
// 2 + a == 3
|
||||
// 2 - a == 3
|
||||
// 2 * a == 3
|
||||
// 2 / a == 3
|
||||
// 2 % a == 3
|
||||
|
||||
switch arithExpr.GetOp() {
|
||||
case planpb.ArithOpType_Add, planpb.ArithOpType_Mul:
|
||||
return combineBinaryArithExpr(op, arithExpr.GetOp(), rightExpr.GetInfo(), leftValue.GetValue(), valueExpr.GetValue()), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("todo")
|
||||
}
|
||||
} else {
|
||||
// (a + b) / 2 == 3
|
||||
return nil, fmt.Errorf("complicated arithmetic operations are not supported")
|
||||
}
|
||||
}
|
||||
|
||||
func handleCompareRightValue(op planpb.OpType, left *ExprWithType, right *planpb.ValueExpr) (*planpb.Expr, error) {
|
||||
castedValue, err := castValue(left.dataType, right.GetValue())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if leftArithExpr := left.expr.GetBinaryArithExpr(); leftArithExpr != nil {
|
||||
return handleBinaryArithExpr(op, leftArithExpr, &planpb.ValueExpr{Value: castedValue})
|
||||
}
|
||||
|
||||
columnInfo := toColumnInfo(left)
|
||||
if columnInfo == nil {
|
||||
return nil, fmt.Errorf("not supported to combine multiple fields")
|
||||
}
|
||||
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_UnaryRangeExpr{
|
||||
UnaryRangeExpr: &planpb.UnaryRangeExpr{
|
||||
ColumnInfo: columnInfo,
|
||||
Op: op,
|
||||
Value: castedValue,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
switch op {
|
||||
case planpb.OpType_Invalid:
|
||||
return nil, fmt.Errorf("unsupported op type: %s", op)
|
||||
default:
|
||||
return expr, nil
|
||||
}
|
||||
}
|
||||
|
||||
func handleCompare(op planpb.OpType, left *ExprWithType, right *ExprWithType) (*planpb.Expr, error) {
|
||||
leftColumnInfo := toColumnInfo(left)
|
||||
rightColumnInfo := toColumnInfo(right)
|
||||
|
||||
if leftColumnInfo == nil || rightColumnInfo == nil {
|
||||
return nil, fmt.Errorf("only comparison between two fields is supported")
|
||||
}
|
||||
|
||||
expr := &planpb.Expr{
|
||||
Expr: &planpb.Expr_CompareExpr{
|
||||
CompareExpr: &planpb.CompareExpr{
|
||||
LeftColumnInfo: leftColumnInfo,
|
||||
RightColumnInfo: rightColumnInfo,
|
||||
Op: op,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
switch op {
|
||||
case planpb.OpType_Invalid:
|
||||
return nil, fmt.Errorf("unsupported op type: %s", op)
|
||||
default:
|
||||
return expr, nil
|
||||
}
|
||||
}
|
||||
|
||||
func HandleCompare(op int, left, right *ExprWithType) (*planpb.Expr, error) {
|
||||
cmpOp := cmpOpMap[op]
|
||||
if valueExpr := left.expr.GetValueExpr(); valueExpr != nil {
|
||||
op, err := reverseOrder(cmpOp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return handleCompareRightValue(op, right, valueExpr)
|
||||
} else if valueExpr := right.expr.GetValueExpr(); valueExpr != nil {
|
||||
return handleCompareRightValue(cmpOp, left, valueExpr)
|
||||
} else {
|
||||
return handleCompare(cmpOp, left, right)
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ enum OpType {
|
|||
NotEqual = 6;
|
||||
PrefixMatch = 7; // startsWith
|
||||
PostfixMatch = 8; // endsWith
|
||||
Match = 9; // like
|
||||
};
|
||||
|
||||
enum ArithOpType {
|
||||
|
@ -48,16 +49,20 @@ message ColumnInfo {
|
|||
bool is_autoID = 4;
|
||||
}
|
||||
|
||||
// For example: a startsWith "prefix", a >= "str", b < 2 and etc,
|
||||
// where both a and b are field in schema.
|
||||
message ColumnExpr {
|
||||
ColumnInfo info = 1;
|
||||
}
|
||||
|
||||
message ValueExpr {
|
||||
GenericValue value = 1;
|
||||
}
|
||||
|
||||
message UnaryRangeExpr {
|
||||
ColumnInfo column_info = 1;
|
||||
OpType op = 2;
|
||||
GenericValue value = 3;
|
||||
}
|
||||
|
||||
// For example: "str1" < a <= "str9", 1 <= b < 9 and etc,
|
||||
// where both a and b are field in schema.
|
||||
message BinaryRangeExpr {
|
||||
ColumnInfo column_info = 1;
|
||||
bool lower_inclusive = 2;
|
||||
|
@ -66,22 +71,17 @@ message BinaryRangeExpr {
|
|||
GenericValue upper_value = 5;
|
||||
}
|
||||
|
||||
// For example: a startsWith b, a >= b, a < b, a == b and etc,
|
||||
// where both a and b are field in schema.
|
||||
message CompareExpr {
|
||||
ColumnInfo left_column_info = 1;
|
||||
ColumnInfo right_column_info = 2;
|
||||
OpType op = 3;
|
||||
}
|
||||
|
||||
// For example: a in ["term0", "term1"], b in [1, 2, 3, 4] and etc,
|
||||
// where both a and b are field in schema.
|
||||
message TermExpr {
|
||||
ColumnInfo column_info = 1;
|
||||
repeated GenericValue values = 2;
|
||||
}
|
||||
|
||||
// !(expr).
|
||||
message UnaryExpr {
|
||||
enum UnaryOp {
|
||||
Invalid = 0;
|
||||
|
@ -91,7 +91,6 @@ message UnaryExpr {
|
|||
Expr child = 2;
|
||||
}
|
||||
|
||||
// (expr) op (expr), where op is of (LogicalAnd, LogicalOr).
|
||||
message BinaryExpr {
|
||||
enum BinaryOp {
|
||||
Invalid = 0;
|
||||
|
@ -109,6 +108,12 @@ message BinaryArithOp {
|
|||
GenericValue right_operand = 3;
|
||||
}
|
||||
|
||||
message BinaryArithExpr {
|
||||
Expr left = 1;
|
||||
Expr right = 2;
|
||||
ArithOpType op = 3;
|
||||
}
|
||||
|
||||
message BinaryArithOpEvalRangeExpr {
|
||||
ColumnInfo column_info = 1;
|
||||
ArithOpType arith_op = 2;
|
||||
|
@ -126,6 +131,9 @@ message Expr {
|
|||
UnaryRangeExpr unary_range_expr = 5;
|
||||
BinaryRangeExpr binary_range_expr = 6;
|
||||
BinaryArithOpEvalRangeExpr binary_arith_op_eval_range_expr = 7;
|
||||
BinaryArithExpr binary_arith_expr = 8;
|
||||
ValueExpr value_expr = 9;
|
||||
ColumnExpr column_expr = 10;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ const (
|
|||
OpType_NotEqual OpType = 6
|
||||
OpType_PrefixMatch OpType = 7
|
||||
OpType_PostfixMatch OpType = 8
|
||||
OpType_Match OpType = 9
|
||||
)
|
||||
|
||||
var OpType_name = map[int32]string{
|
||||
|
@ -45,6 +46,7 @@ var OpType_name = map[int32]string{
|
|||
6: "NotEqual",
|
||||
7: "PrefixMatch",
|
||||
8: "PostfixMatch",
|
||||
9: "Match",
|
||||
}
|
||||
|
||||
var OpType_value = map[string]int32{
|
||||
|
@ -57,6 +59,7 @@ var OpType_value = map[string]int32{
|
|||
"NotEqual": 6,
|
||||
"PrefixMatch": 7,
|
||||
"PostfixMatch": 8,
|
||||
"Match": 9,
|
||||
}
|
||||
|
||||
func (x OpType) String() string {
|
||||
|
@ -126,7 +129,7 @@ func (x UnaryExpr_UnaryOp) String() string {
|
|||
}
|
||||
|
||||
func (UnaryExpr_UnaryOp) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{7, 0}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{9, 0}
|
||||
}
|
||||
|
||||
type BinaryExpr_BinaryOp int32
|
||||
|
@ -154,7 +157,7 @@ func (x BinaryExpr_BinaryOp) String() string {
|
|||
}
|
||||
|
||||
func (BinaryExpr_BinaryOp) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{8, 0}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{10, 0}
|
||||
}
|
||||
|
||||
type GenericValue struct {
|
||||
|
@ -393,8 +396,84 @@ func (m *ColumnInfo) GetIsAutoID() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// For example: a startsWith "prefix", a >= "str", b < 2 and etc,
|
||||
// where both a and b are field in schema.
|
||||
type ColumnExpr struct {
|
||||
Info *ColumnInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ColumnExpr) Reset() { *m = ColumnExpr{} }
|
||||
func (m *ColumnExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*ColumnExpr) ProtoMessage() {}
|
||||
func (*ColumnExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{3}
|
||||
}
|
||||
|
||||
func (m *ColumnExpr) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ColumnExpr.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ColumnExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ColumnExpr.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ColumnExpr) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ColumnExpr.Merge(m, src)
|
||||
}
|
||||
func (m *ColumnExpr) XXX_Size() int {
|
||||
return xxx_messageInfo_ColumnExpr.Size(m)
|
||||
}
|
||||
func (m *ColumnExpr) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ColumnExpr.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ColumnExpr proto.InternalMessageInfo
|
||||
|
||||
func (m *ColumnExpr) GetInfo() *ColumnInfo {
|
||||
if m != nil {
|
||||
return m.Info
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ValueExpr struct {
|
||||
Value *GenericValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ValueExpr) Reset() { *m = ValueExpr{} }
|
||||
func (m *ValueExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*ValueExpr) ProtoMessage() {}
|
||||
func (*ValueExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{4}
|
||||
}
|
||||
|
||||
func (m *ValueExpr) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ValueExpr.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ValueExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ValueExpr.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ValueExpr) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ValueExpr.Merge(m, src)
|
||||
}
|
||||
func (m *ValueExpr) XXX_Size() int {
|
||||
return xxx_messageInfo_ValueExpr.Size(m)
|
||||
}
|
||||
func (m *ValueExpr) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ValueExpr.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ValueExpr proto.InternalMessageInfo
|
||||
|
||||
func (m *ValueExpr) GetValue() *GenericValue {
|
||||
if m != nil {
|
||||
return m.Value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type UnaryRangeExpr struct {
|
||||
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
|
||||
Op OpType `protobuf:"varint,2,opt,name=op,proto3,enum=milvus.proto.plan.OpType" json:"op,omitempty"`
|
||||
|
@ -408,7 +487,7 @@ func (m *UnaryRangeExpr) Reset() { *m = UnaryRangeExpr{} }
|
|||
func (m *UnaryRangeExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*UnaryRangeExpr) ProtoMessage() {}
|
||||
func (*UnaryRangeExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{3}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{5}
|
||||
}
|
||||
|
||||
func (m *UnaryRangeExpr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -450,8 +529,6 @@ func (m *UnaryRangeExpr) GetValue() *GenericValue {
|
|||
return nil
|
||||
}
|
||||
|
||||
// For example: "str1" < a <= "str9", 1 <= b < 9 and etc,
|
||||
// where both a and b are field in schema.
|
||||
type BinaryRangeExpr struct {
|
||||
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
|
||||
LowerInclusive bool `protobuf:"varint,2,opt,name=lower_inclusive,json=lowerInclusive,proto3" json:"lower_inclusive,omitempty"`
|
||||
|
@ -467,7 +544,7 @@ func (m *BinaryRangeExpr) Reset() { *m = BinaryRangeExpr{} }
|
|||
func (m *BinaryRangeExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*BinaryRangeExpr) ProtoMessage() {}
|
||||
func (*BinaryRangeExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{4}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{6}
|
||||
}
|
||||
|
||||
func (m *BinaryRangeExpr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -523,8 +600,6 @@ func (m *BinaryRangeExpr) GetUpperValue() *GenericValue {
|
|||
return nil
|
||||
}
|
||||
|
||||
// For example: a startsWith b, a >= b, a < b, a == b and etc,
|
||||
// where both a and b are field in schema.
|
||||
type CompareExpr struct {
|
||||
LeftColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=left_column_info,json=leftColumnInfo,proto3" json:"left_column_info,omitempty"`
|
||||
RightColumnInfo *ColumnInfo `protobuf:"bytes,2,opt,name=right_column_info,json=rightColumnInfo,proto3" json:"right_column_info,omitempty"`
|
||||
|
@ -538,7 +613,7 @@ func (m *CompareExpr) Reset() { *m = CompareExpr{} }
|
|||
func (m *CompareExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*CompareExpr) ProtoMessage() {}
|
||||
func (*CompareExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{5}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{7}
|
||||
}
|
||||
|
||||
func (m *CompareExpr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -580,8 +655,6 @@ func (m *CompareExpr) GetOp() OpType {
|
|||
return OpType_Invalid
|
||||
}
|
||||
|
||||
// For example: a in ["term0", "term1"], b in [1, 2, 3, 4] and etc,
|
||||
// where both a and b are field in schema.
|
||||
type TermExpr struct {
|
||||
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
|
||||
Values []*GenericValue `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"`
|
||||
|
@ -594,7 +667,7 @@ func (m *TermExpr) Reset() { *m = TermExpr{} }
|
|||
func (m *TermExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*TermExpr) ProtoMessage() {}
|
||||
func (*TermExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{6}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{8}
|
||||
}
|
||||
|
||||
func (m *TermExpr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -629,7 +702,6 @@ func (m *TermExpr) GetValues() []*GenericValue {
|
|||
return nil
|
||||
}
|
||||
|
||||
// !(expr).
|
||||
type UnaryExpr struct {
|
||||
Op UnaryExpr_UnaryOp `protobuf:"varint,1,opt,name=op,proto3,enum=milvus.proto.plan.UnaryExpr_UnaryOp" json:"op,omitempty"`
|
||||
Child *Expr `protobuf:"bytes,2,opt,name=child,proto3" json:"child,omitempty"`
|
||||
|
@ -642,7 +714,7 @@ func (m *UnaryExpr) Reset() { *m = UnaryExpr{} }
|
|||
func (m *UnaryExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*UnaryExpr) ProtoMessage() {}
|
||||
func (*UnaryExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{7}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{9}
|
||||
}
|
||||
|
||||
func (m *UnaryExpr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -677,7 +749,6 @@ func (m *UnaryExpr) GetChild() *Expr {
|
|||
return nil
|
||||
}
|
||||
|
||||
// (expr) op (expr), where op is of (LogicalAnd, LogicalOr).
|
||||
type BinaryExpr struct {
|
||||
Op BinaryExpr_BinaryOp `protobuf:"varint,1,opt,name=op,proto3,enum=milvus.proto.plan.BinaryExpr_BinaryOp" json:"op,omitempty"`
|
||||
Left *Expr `protobuf:"bytes,2,opt,name=left,proto3" json:"left,omitempty"`
|
||||
|
@ -691,7 +762,7 @@ func (m *BinaryExpr) Reset() { *m = BinaryExpr{} }
|
|||
func (m *BinaryExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*BinaryExpr) ProtoMessage() {}
|
||||
func (*BinaryExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{8}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{10}
|
||||
}
|
||||
|
||||
func (m *BinaryExpr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -746,7 +817,7 @@ func (m *BinaryArithOp) Reset() { *m = BinaryArithOp{} }
|
|||
func (m *BinaryArithOp) String() string { return proto.CompactTextString(m) }
|
||||
func (*BinaryArithOp) ProtoMessage() {}
|
||||
func (*BinaryArithOp) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{9}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{11}
|
||||
}
|
||||
|
||||
func (m *BinaryArithOp) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -788,6 +859,61 @@ func (m *BinaryArithOp) GetRightOperand() *GenericValue {
|
|||
return nil
|
||||
}
|
||||
|
||||
type BinaryArithExpr struct {
|
||||
Left *Expr `protobuf:"bytes,1,opt,name=left,proto3" json:"left,omitempty"`
|
||||
Right *Expr `protobuf:"bytes,2,opt,name=right,proto3" json:"right,omitempty"`
|
||||
Op ArithOpType `protobuf:"varint,3,opt,name=op,proto3,enum=milvus.proto.plan.ArithOpType" json:"op,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *BinaryArithExpr) Reset() { *m = BinaryArithExpr{} }
|
||||
func (m *BinaryArithExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*BinaryArithExpr) ProtoMessage() {}
|
||||
func (*BinaryArithExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{12}
|
||||
}
|
||||
|
||||
func (m *BinaryArithExpr) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_BinaryArithExpr.Unmarshal(m, b)
|
||||
}
|
||||
func (m *BinaryArithExpr) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_BinaryArithExpr.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *BinaryArithExpr) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BinaryArithExpr.Merge(m, src)
|
||||
}
|
||||
func (m *BinaryArithExpr) XXX_Size() int {
|
||||
return xxx_messageInfo_BinaryArithExpr.Size(m)
|
||||
}
|
||||
func (m *BinaryArithExpr) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BinaryArithExpr.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BinaryArithExpr proto.InternalMessageInfo
|
||||
|
||||
func (m *BinaryArithExpr) GetLeft() *Expr {
|
||||
if m != nil {
|
||||
return m.Left
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BinaryArithExpr) GetRight() *Expr {
|
||||
if m != nil {
|
||||
return m.Right
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BinaryArithExpr) GetOp() ArithOpType {
|
||||
if m != nil {
|
||||
return m.Op
|
||||
}
|
||||
return ArithOpType_Unknown
|
||||
}
|
||||
|
||||
type BinaryArithOpEvalRangeExpr struct {
|
||||
ColumnInfo *ColumnInfo `protobuf:"bytes,1,opt,name=column_info,json=columnInfo,proto3" json:"column_info,omitempty"`
|
||||
ArithOp ArithOpType `protobuf:"varint,2,opt,name=arith_op,json=arithOp,proto3,enum=milvus.proto.plan.ArithOpType" json:"arith_op,omitempty"`
|
||||
|
@ -803,7 +929,7 @@ func (m *BinaryArithOpEvalRangeExpr) Reset() { *m = BinaryArithOpEvalRan
|
|||
func (m *BinaryArithOpEvalRangeExpr) String() string { return proto.CompactTextString(m) }
|
||||
func (*BinaryArithOpEvalRangeExpr) ProtoMessage() {}
|
||||
func (*BinaryArithOpEvalRangeExpr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{10}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{13}
|
||||
}
|
||||
|
||||
func (m *BinaryArithOpEvalRangeExpr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -868,6 +994,9 @@ type Expr struct {
|
|||
// *Expr_UnaryRangeExpr
|
||||
// *Expr_BinaryRangeExpr
|
||||
// *Expr_BinaryArithOpEvalRangeExpr
|
||||
// *Expr_BinaryArithExpr
|
||||
// *Expr_ValueExpr
|
||||
// *Expr_ColumnExpr
|
||||
Expr isExpr_Expr `protobuf_oneof:"expr"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
|
@ -878,7 +1007,7 @@ func (m *Expr) Reset() { *m = Expr{} }
|
|||
func (m *Expr) String() string { return proto.CompactTextString(m) }
|
||||
func (*Expr) ProtoMessage() {}
|
||||
func (*Expr) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{11}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{14}
|
||||
}
|
||||
|
||||
func (m *Expr) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -931,6 +1060,18 @@ type Expr_BinaryArithOpEvalRangeExpr struct {
|
|||
BinaryArithOpEvalRangeExpr *BinaryArithOpEvalRangeExpr `protobuf:"bytes,7,opt,name=binary_arith_op_eval_range_expr,json=binaryArithOpEvalRangeExpr,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Expr_BinaryArithExpr struct {
|
||||
BinaryArithExpr *BinaryArithExpr `protobuf:"bytes,8,opt,name=binary_arith_expr,json=binaryArithExpr,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Expr_ValueExpr struct {
|
||||
ValueExpr *ValueExpr `protobuf:"bytes,9,opt,name=value_expr,json=valueExpr,proto3,oneof"`
|
||||
}
|
||||
|
||||
type Expr_ColumnExpr struct {
|
||||
ColumnExpr *ColumnExpr `protobuf:"bytes,10,opt,name=column_expr,json=columnExpr,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Expr_TermExpr) isExpr_Expr() {}
|
||||
|
||||
func (*Expr_UnaryExpr) isExpr_Expr() {}
|
||||
|
@ -945,6 +1086,12 @@ func (*Expr_BinaryRangeExpr) isExpr_Expr() {}
|
|||
|
||||
func (*Expr_BinaryArithOpEvalRangeExpr) isExpr_Expr() {}
|
||||
|
||||
func (*Expr_BinaryArithExpr) isExpr_Expr() {}
|
||||
|
||||
func (*Expr_ValueExpr) isExpr_Expr() {}
|
||||
|
||||
func (*Expr_ColumnExpr) isExpr_Expr() {}
|
||||
|
||||
func (m *Expr) GetExpr() isExpr_Expr {
|
||||
if m != nil {
|
||||
return m.Expr
|
||||
|
@ -1001,6 +1148,27 @@ func (m *Expr) GetBinaryArithOpEvalRangeExpr() *BinaryArithOpEvalRangeExpr {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *Expr) GetBinaryArithExpr() *BinaryArithExpr {
|
||||
if x, ok := m.GetExpr().(*Expr_BinaryArithExpr); ok {
|
||||
return x.BinaryArithExpr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Expr) GetValueExpr() *ValueExpr {
|
||||
if x, ok := m.GetExpr().(*Expr_ValueExpr); ok {
|
||||
return x.ValueExpr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Expr) GetColumnExpr() *ColumnExpr {
|
||||
if x, ok := m.GetExpr().(*Expr_ColumnExpr); ok {
|
||||
return x.ColumnExpr
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// XXX_OneofWrappers is for the internal use of the proto package.
|
||||
func (*Expr) XXX_OneofWrappers() []interface{} {
|
||||
return []interface{}{
|
||||
|
@ -1011,6 +1179,9 @@ func (*Expr) XXX_OneofWrappers() []interface{} {
|
|||
(*Expr_UnaryRangeExpr)(nil),
|
||||
(*Expr_BinaryRangeExpr)(nil),
|
||||
(*Expr_BinaryArithOpEvalRangeExpr)(nil),
|
||||
(*Expr_BinaryArithExpr)(nil),
|
||||
(*Expr_ValueExpr)(nil),
|
||||
(*Expr_ColumnExpr)(nil),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1029,7 +1200,7 @@ func (m *VectorANNS) Reset() { *m = VectorANNS{} }
|
|||
func (m *VectorANNS) String() string { return proto.CompactTextString(m) }
|
||||
func (*VectorANNS) ProtoMessage() {}
|
||||
func (*VectorANNS) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{12}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{15}
|
||||
}
|
||||
|
||||
func (m *VectorANNS) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -1100,7 +1271,7 @@ func (m *PlanNode) Reset() { *m = PlanNode{} }
|
|||
func (m *PlanNode) String() string { return proto.CompactTextString(m) }
|
||||
func (*PlanNode) ProtoMessage() {}
|
||||
func (*PlanNode) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{13}
|
||||
return fileDescriptor_2d655ab2f7683c23, []int{16}
|
||||
}
|
||||
|
||||
func (m *PlanNode) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -1181,6 +1352,8 @@ func init() {
|
|||
proto.RegisterType((*GenericValue)(nil), "milvus.proto.plan.GenericValue")
|
||||
proto.RegisterType((*QueryInfo)(nil), "milvus.proto.plan.QueryInfo")
|
||||
proto.RegisterType((*ColumnInfo)(nil), "milvus.proto.plan.ColumnInfo")
|
||||
proto.RegisterType((*ColumnExpr)(nil), "milvus.proto.plan.ColumnExpr")
|
||||
proto.RegisterType((*ValueExpr)(nil), "milvus.proto.plan.ValueExpr")
|
||||
proto.RegisterType((*UnaryRangeExpr)(nil), "milvus.proto.plan.UnaryRangeExpr")
|
||||
proto.RegisterType((*BinaryRangeExpr)(nil), "milvus.proto.plan.BinaryRangeExpr")
|
||||
proto.RegisterType((*CompareExpr)(nil), "milvus.proto.plan.CompareExpr")
|
||||
|
@ -1188,6 +1361,7 @@ func init() {
|
|||
proto.RegisterType((*UnaryExpr)(nil), "milvus.proto.plan.UnaryExpr")
|
||||
proto.RegisterType((*BinaryExpr)(nil), "milvus.proto.plan.BinaryExpr")
|
||||
proto.RegisterType((*BinaryArithOp)(nil), "milvus.proto.plan.BinaryArithOp")
|
||||
proto.RegisterType((*BinaryArithExpr)(nil), "milvus.proto.plan.BinaryArithExpr")
|
||||
proto.RegisterType((*BinaryArithOpEvalRangeExpr)(nil), "milvus.proto.plan.BinaryArithOpEvalRangeExpr")
|
||||
proto.RegisterType((*Expr)(nil), "milvus.proto.plan.Expr")
|
||||
proto.RegisterType((*VectorANNS)(nil), "milvus.proto.plan.VectorANNS")
|
||||
|
@ -1197,86 +1371,92 @@ func init() {
|
|||
func init() { proto.RegisterFile("plan.proto", fileDescriptor_2d655ab2f7683c23) }
|
||||
|
||||
var fileDescriptor_2d655ab2f7683c23 = []byte{
|
||||
// 1284 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x56, 0xcd, 0x72, 0xdb, 0x36,
|
||||
0x10, 0x16, 0x45, 0xc9, 0x22, 0x97, 0xb2, 0xcc, 0xf0, 0xd2, 0xfc, 0x34, 0xb1, 0xcb, 0x66, 0x1a,
|
||||
0x37, 0x9d, 0xd8, 0xd3, 0x24, 0x4d, 0x26, 0xe9, 0xb4, 0x13, 0xff, 0xa4, 0x96, 0xa7, 0x89, 0xed,
|
||||
0x32, 0x8e, 0x0f, 0xbd, 0x70, 0x20, 0x12, 0x96, 0x30, 0x81, 0x00, 0x06, 0x04, 0x95, 0xe8, 0xdc,
|
||||
0x5b, 0x6f, 0x79, 0x89, 0xf6, 0xde, 0x5b, 0x4f, 0x7d, 0x81, 0x1e, 0x7a, 0xec, 0xbd, 0x2f, 0xd2,
|
||||
0x01, 0x40, 0xeb, 0x27, 0x23, 0x25, 0xca, 0xd4, 0x33, 0xbd, 0x01, 0x8b, 0xdd, 0x0f, 0xfb, 0x2d,
|
||||
0x76, 0x17, 0x0b, 0x90, 0x51, 0xc4, 0x36, 0x32, 0xc1, 0x25, 0x0f, 0x2e, 0xf4, 0x09, 0x1d, 0x14,
|
||||
0xb9, 0xd9, 0x6d, 0xa8, 0x83, 0xcb, 0xcd, 0x3c, 0xe9, 0xe1, 0x3e, 0x32, 0xa2, 0xf0, 0x8d, 0x05,
|
||||
0xcd, 0x3d, 0xcc, 0xb0, 0x20, 0xc9, 0x09, 0xa2, 0x05, 0x0e, 0xae, 0x80, 0xd3, 0xe1, 0x9c, 0xc6,
|
||||
0x03, 0x44, 0x2f, 0x5a, 0x6b, 0xd6, 0xba, 0xd3, 0xae, 0x44, 0x0d, 0x25, 0x39, 0x41, 0x34, 0xb8,
|
||||
0x0a, 0x2e, 0x61, 0xf2, 0xde, 0x5d, 0x7d, 0x5a, 0x5d, 0xb3, 0xd6, 0xed, 0x76, 0x25, 0x72, 0xb4,
|
||||
0xa8, 0x3c, 0x3e, 0xa5, 0x1c, 0x49, 0x7d, 0x6c, 0xaf, 0x59, 0xeb, 0x96, 0x3a, 0xd6, 0x22, 0x75,
|
||||
0xbc, 0x0a, 0x90, 0x4b, 0x41, 0x58, 0x57, 0x9f, 0xd7, 0xd6, 0xac, 0x75, 0xb7, 0x5d, 0x89, 0x5c,
|
||||
0x23, 0x3b, 0x41, 0x74, 0xbb, 0x0e, 0xf6, 0x00, 0xd1, 0xf0, 0x67, 0x0b, 0xdc, 0x1f, 0x0a, 0x2c,
|
||||
0x86, 0xfb, 0xec, 0x94, 0x07, 0x01, 0xd4, 0x24, 0xcf, 0x5e, 0x68, 0x67, 0xec, 0x48, 0xaf, 0x83,
|
||||
0x55, 0xf0, 0xfa, 0x58, 0x0a, 0x92, 0xc4, 0x72, 0x98, 0x61, 0x7d, 0x95, 0x1b, 0x81, 0x11, 0x1d,
|
||||
0x0f, 0x33, 0x1c, 0x7c, 0x0a, 0xcb, 0x39, 0x46, 0x22, 0xe9, 0xc5, 0x19, 0x12, 0xa8, 0x9f, 0x9b,
|
||||
0xdb, 0xa2, 0xa6, 0x11, 0x1e, 0x69, 0x99, 0x52, 0x12, 0xbc, 0x60, 0x69, 0x9c, 0xe2, 0x84, 0xf4,
|
||||
0x11, 0xbd, 0x58, 0xd7, 0x57, 0x34, 0xb5, 0x70, 0xd7, 0xc8, 0xc2, 0x5f, 0x2c, 0x80, 0x1d, 0x4e,
|
||||
0x8b, 0x3e, 0xd3, 0xde, 0x5c, 0x02, 0xe7, 0x94, 0x60, 0x9a, 0xc6, 0x24, 0x2d, 0x3d, 0x6a, 0xe8,
|
||||
0xfd, 0x7e, 0x1a, 0x3c, 0x04, 0x37, 0x45, 0x12, 0x19, 0x97, 0x54, 0x70, 0x5a, 0xb7, 0xaf, 0x6e,
|
||||
0x4c, 0xc5, 0xbf, 0x8c, 0xfc, 0x2e, 0x92, 0x48, 0x79, 0x19, 0x39, 0x69, 0xb9, 0x0a, 0xae, 0x43,
|
||||
0x8b, 0xe4, 0x71, 0x26, 0x48, 0x1f, 0x89, 0x61, 0xfc, 0x02, 0x0f, 0x35, 0x27, 0x27, 0x6a, 0x92,
|
||||
0xfc, 0xc8, 0x08, 0xbf, 0xc7, 0xc3, 0xe0, 0x0a, 0xb8, 0x24, 0x8f, 0x51, 0x21, 0xf9, 0xfe, 0xae,
|
||||
0x66, 0xe4, 0x44, 0x0e, 0xc9, 0xb7, 0xf4, 0x3e, 0xfc, 0xcd, 0x82, 0xd6, 0x73, 0x86, 0xc4, 0x30,
|
||||
0x42, 0xac, 0x8b, 0x1f, 0xbf, 0xce, 0x44, 0xf0, 0x2d, 0x78, 0x89, 0x76, 0x3d, 0x26, 0xec, 0x94,
|
||||
0x6b, 0x7f, 0xbd, 0xb7, 0x7d, 0xd2, 0xc9, 0x32, 0x26, 0x18, 0x41, 0x32, 0x26, 0xfb, 0x39, 0x54,
|
||||
0x79, 0x56, 0x52, 0xb9, 0x34, 0xc3, 0xec, 0x30, 0xd3, 0x34, 0xaa, 0x3c, 0x0b, 0xbe, 0x82, 0xfa,
|
||||
0x40, 0xe5, 0x8f, 0xf6, 0xdb, 0xbb, 0xbd, 0x3a, 0x43, 0x7b, 0x32, 0xcd, 0x22, 0xa3, 0x1d, 0xfe,
|
||||
0x5a, 0x85, 0x95, 0x6d, 0x72, 0xbe, 0x5e, 0xdf, 0x80, 0x15, 0xca, 0x5f, 0x61, 0x11, 0x13, 0x96,
|
||||
0xd0, 0x22, 0x27, 0x03, 0xf3, 0x1a, 0x4e, 0xd4, 0xd2, 0xe2, 0xfd, 0x33, 0xa9, 0x52, 0x2c, 0xb2,
|
||||
0x6c, 0x4a, 0xd1, 0x44, 0xbd, 0xa5, 0xc5, 0x63, 0xc5, 0x47, 0xe0, 0x19, 0x44, 0x43, 0xb1, 0xb6,
|
||||
0x18, 0x45, 0xd0, 0x36, 0xa6, 0xaa, 0x1e, 0x81, 0x67, 0xae, 0x32, 0x08, 0xf5, 0x05, 0x11, 0xb4,
|
||||
0x8d, 0x5e, 0x87, 0x7f, 0x5a, 0xe0, 0xed, 0xf0, 0x7e, 0x86, 0x84, 0x89, 0xd2, 0x1e, 0xf8, 0x14,
|
||||
0x9f, 0xca, 0xf8, 0x83, 0x43, 0xd5, 0x52, 0x66, 0x13, 0x19, 0xbd, 0x0f, 0x17, 0x04, 0xe9, 0xf6,
|
||||
0xa6, 0x91, 0xaa, 0x8b, 0x20, 0xad, 0x68, 0xbb, 0x9d, 0xb7, 0xf3, 0xc5, 0x5e, 0x20, 0x5f, 0xc2,
|
||||
0x9f, 0x2c, 0x70, 0x8e, 0xb1, 0xe8, 0x9f, 0xcb, 0x8b, 0xdf, 0x87, 0x25, 0x1d, 0xd7, 0xfc, 0x62,
|
||||
0x75, 0xcd, 0x5e, 0x24, 0xb0, 0xa5, 0xba, 0xea, 0x7e, 0xae, 0xae, 0x19, 0xed, 0xc6, 0x5d, 0xed,
|
||||
0xbe, 0xa5, 0xdd, 0xbf, 0x3e, 0x03, 0x62, 0xa4, 0x69, 0x56, 0x87, 0x99, 0xce, 0xfc, 0x5b, 0x50,
|
||||
0x4f, 0x7a, 0x84, 0xa6, 0x65, 0xcc, 0x3e, 0x9a, 0x61, 0xa8, 0x6c, 0x22, 0xa3, 0x15, 0xae, 0x42,
|
||||
0xa3, 0xb4, 0x0e, 0x3c, 0x68, 0xec, 0xb3, 0x01, 0xa2, 0x24, 0xf5, 0x2b, 0x41, 0x03, 0xec, 0x03,
|
||||
0x2e, 0x7d, 0x2b, 0xfc, 0xdb, 0x02, 0x30, 0x25, 0xa1, 0x9d, 0xba, 0x37, 0xe1, 0xd4, 0x67, 0x33,
|
||||
0xb0, 0xc7, 0xaa, 0xe5, 0xb2, 0x74, 0xeb, 0x0b, 0xa8, 0xa9, 0x87, 0x7e, 0x9f, 0x57, 0x5a, 0x49,
|
||||
0x71, 0xd0, 0x6f, 0x59, 0x56, 0xef, 0x7c, 0x0e, 0x5a, 0x2b, 0xbc, 0x07, 0xce, 0xd9, 0x5d, 0xd3,
|
||||
0x24, 0x5a, 0x00, 0x4f, 0x78, 0x97, 0x24, 0x88, 0x6e, 0xb1, 0xd4, 0xb7, 0x82, 0x65, 0x70, 0xcb,
|
||||
0xfd, 0xa1, 0xf0, 0xab, 0xe1, 0x5f, 0x16, 0x2c, 0x1b, 0xc3, 0x2d, 0x41, 0x64, 0xef, 0x30, 0xfb,
|
||||
0xcf, 0x2f, 0xff, 0x00, 0x1c, 0xa4, 0xa0, 0xe2, 0x51, 0x9f, 0xba, 0x36, 0xc3, 0xb8, 0xbc, 0x4d,
|
||||
0x27, 0x5f, 0x03, 0x95, 0x57, 0xef, 0xc2, 0xb2, 0xc9, 0x7b, 0x9e, 0x61, 0x81, 0x58, 0xba, 0x68,
|
||||
0xe7, 0x6a, 0x6a, 0xab, 0x43, 0x63, 0x14, 0xfe, 0x51, 0x85, 0xcb, 0x53, 0x94, 0x1e, 0x0f, 0x10,
|
||||
0x3d, 0xbf, 0x5e, 0xf6, 0x7f, 0xf3, 0x2b, 0x4b, 0xba, 0xf6, 0x41, 0x5f, 0x40, 0xfd, 0xc3, 0xbe,
|
||||
0x80, 0x1a, 0xd4, 0x74, 0xac, 0x1e, 0x82, 0x2b, 0xb1, 0xe8, 0xc7, 0xf8, 0x75, 0x26, 0xca, 0x48,
|
||||
0x5d, 0x99, 0x81, 0x71, 0xd6, 0x35, 0xd4, 0x68, 0x21, 0xcf, 0x3a, 0xc8, 0x37, 0x00, 0x85, 0x7a,
|
||||
0x04, 0x63, 0x6c, 0x72, 0xfe, 0xe3, 0x77, 0x95, 0xb0, 0x1a, 0x3c, 0x8a, 0x51, 0x91, 0x3d, 0x02,
|
||||
0xaf, 0x43, 0xc6, 0xf6, 0xf6, 0xdc, 0x67, 0x1a, 0x57, 0x5b, 0xbb, 0x12, 0x41, 0x67, 0x5c, 0xa6,
|
||||
0x3b, 0xd0, 0x4c, 0x4c, 0x77, 0x36, 0x10, 0xe6, 0x8f, 0xb8, 0x36, 0xf3, 0xa5, 0x47, 0x4d, 0xbc,
|
||||
0x5d, 0x89, 0xbc, 0x64, 0xa2, 0xa7, 0x3f, 0x05, 0xdf, 0xb0, 0x10, 0x2a, 0x81, 0x0c, 0x90, 0x09,
|
||||
0xe6, 0x27, 0xf3, 0xb8, 0x8c, 0x52, 0xad, 0x5d, 0x89, 0x5a, 0xc5, 0xf4, 0x47, 0x7a, 0x04, 0x17,
|
||||
0x4a, 0x56, 0x13, 0x78, 0x4b, 0x1a, 0x2f, 0x9c, 0xcb, 0x6d, 0x12, 0x70, 0xa5, 0xf3, 0xd6, 0xd7,
|
||||
0x2c, 0x61, 0xb5, 0x44, 0x3c, 0xcb, 0xca, 0x18, 0x0f, 0x10, 0x9d, 0xc4, 0x6f, 0x68, 0xfc, 0x5b,
|
||||
0x73, 0xf1, 0x67, 0x95, 0x49, 0xbb, 0x12, 0x5d, 0xee, 0xcc, 0x3d, 0xdd, 0x5e, 0x82, 0x9a, 0x82,
|
||||
0x0e, 0xff, 0xb1, 0x00, 0x4e, 0x70, 0x22, 0xb9, 0xd8, 0x3a, 0x38, 0x78, 0x56, 0x4e, 0x43, 0xc6,
|
||||
0xce, 0x8c, 0xaa, 0x6a, 0x1a, 0x32, 0xb7, 0x4c, 0xcd, 0x69, 0xd5, 0xe9, 0x39, 0xed, 0x3e, 0x40,
|
||||
0x26, 0x70, 0x4a, 0x12, 0x24, 0x71, 0xfe, 0xbe, 0x8e, 0x37, 0xa1, 0x1a, 0x7c, 0x0d, 0xf0, 0x52,
|
||||
0x8d, 0xa5, 0xa6, 0x96, 0x6b, 0x73, 0x93, 0x6c, 0x34, 0xbb, 0x46, 0xee, 0xcb, 0xd1, 0x18, 0x7b,
|
||||
0x03, 0x56, 0x32, 0x8a, 0x12, 0xdc, 0xe3, 0x34, 0xc5, 0x22, 0x96, 0xa8, 0xab, 0x9f, 0xd6, 0x8d,
|
||||
0x5a, 0x13, 0xe2, 0x63, 0xd4, 0x0d, 0x7f, 0xb7, 0xc0, 0x39, 0xa2, 0x88, 0x1d, 0xf0, 0x54, 0xcf,
|
||||
0x0d, 0x03, 0xcd, 0x38, 0x46, 0x8c, 0xe5, 0xef, 0xe8, 0x1f, 0xe3, 0xb8, 0xa8, 0xc4, 0x34, 0x36,
|
||||
0x5b, 0x8c, 0xe5, 0xc1, 0x83, 0x29, 0xb6, 0xef, 0xfe, 0x0d, 0x94, 0xe9, 0x04, 0xdf, 0x75, 0xf0,
|
||||
0x79, 0x21, 0xb3, 0x42, 0xc6, 0x67, 0xa1, 0x54, 0xe1, 0xb2, 0xd7, 0xed, 0xa8, 0x65, 0xe4, 0xdf,
|
||||
0x99, 0x88, 0xe6, 0xea, 0x85, 0x18, 0x4f, 0xf1, 0xcd, 0x37, 0x16, 0x2c, 0x99, 0x8e, 0x30, 0xfd,
|
||||
0x2f, 0xac, 0x80, 0xb7, 0x27, 0x30, 0x92, 0x58, 0x1c, 0xf7, 0x10, 0xf3, 0xad, 0xc0, 0x87, 0x66,
|
||||
0x29, 0x78, 0xfc, 0xb2, 0x40, 0xd4, 0xaf, 0x06, 0x4d, 0x70, 0x9e, 0xe0, 0x3c, 0xd7, 0xe7, 0xb6,
|
||||
0xfe, 0x38, 0x70, 0x9e, 0x9b, 0xc3, 0x5a, 0xe0, 0x42, 0xdd, 0x2c, 0xeb, 0x4a, 0xef, 0x80, 0x4b,
|
||||
0xb3, 0x5b, 0x52, 0xc0, 0x47, 0x02, 0x9f, 0x92, 0xd7, 0x4f, 0x91, 0x4c, 0x7a, 0x7e, 0x43, 0x01,
|
||||
0x1f, 0xf1, 0x5c, 0x8e, 0x24, 0xce, 0xcd, 0x3d, 0xf0, 0x26, 0xfa, 0xa3, 0xf2, 0xeb, 0x39, 0x7b,
|
||||
0xc1, 0xf8, 0x2b, 0x66, 0x3e, 0xdd, 0xad, 0x54, 0x7d, 0x54, 0x0d, 0xb0, 0x9f, 0x15, 0x1d, 0xbf,
|
||||
0xaa, 0x16, 0x4f, 0x0b, 0xea, 0xdb, 0x6a, 0xb1, 0x4b, 0x06, 0x7e, 0x4d, 0x4b, 0x78, 0xea, 0xd7,
|
||||
0xb7, 0xef, 0xfc, 0xf8, 0x65, 0x97, 0xc8, 0x5e, 0xd1, 0xd9, 0x48, 0x78, 0x7f, 0xd3, 0x44, 0xf0,
|
||||
0x16, 0xe1, 0xe5, 0x6a, 0x93, 0x30, 0x89, 0x05, 0x43, 0x74, 0x53, 0x07, 0x75, 0x53, 0x05, 0x35,
|
||||
0xeb, 0x74, 0x96, 0xf4, 0xee, 0xce, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7b, 0x2c, 0x0c, 0x69,
|
||||
0x95, 0x0d, 0x00, 0x00,
|
||||
// 1387 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcd, 0x73, 0xdb, 0x44,
|
||||
0x14, 0xb7, 0x2c, 0x3b, 0x96, 0x9e, 0x1d, 0x47, 0xd5, 0x85, 0x7e, 0xd0, 0x26, 0x88, 0x0e, 0x0d,
|
||||
0x65, 0x9a, 0x4c, 0x69, 0x69, 0xa7, 0x65, 0x0a, 0xf9, 0x2a, 0x49, 0x86, 0x36, 0x09, 0x6a, 0x9a,
|
||||
0x03, 0x17, 0xcd, 0x5a, 0xda, 0xd8, 0x3b, 0x95, 0xb5, 0xea, 0x6a, 0xe5, 0xd6, 0x67, 0x6e, 0xdc,
|
||||
0xb8, 0xc3, 0x15, 0xee, 0xdc, 0x38, 0xf1, 0x0f, 0x70, 0xe0, 0xc8, 0x9d, 0xff, 0x82, 0x13, 0xb3,
|
||||
0x6f, 0xe5, 0xaf, 0x8e, 0xdd, 0x38, 0x43, 0x67, 0xb8, 0xed, 0xbe, 0x7d, 0xef, 0xb7, 0xef, 0xfd,
|
||||
0xf6, 0xed, 0xdb, 0xb7, 0x00, 0x69, 0x4c, 0x92, 0xb5, 0x54, 0x70, 0xc9, 0xdd, 0x0b, 0x5d, 0x16,
|
||||
0xf7, 0xf2, 0x4c, 0xcf, 0xd6, 0xd4, 0xc2, 0xe5, 0x46, 0x16, 0x76, 0x68, 0x97, 0x68, 0x91, 0xf7,
|
||||
0x83, 0x01, 0x8d, 0x5d, 0x9a, 0x50, 0xc1, 0xc2, 0x13, 0x12, 0xe7, 0xd4, 0xbd, 0x02, 0x56, 0x8b,
|
||||
0xf3, 0x38, 0xe8, 0x91, 0xf8, 0xa2, 0xb1, 0x62, 0xac, 0x5a, 0x7b, 0x25, 0xbf, 0xa6, 0x24, 0x27,
|
||||
0x24, 0x76, 0xaf, 0x82, 0xcd, 0x12, 0x79, 0xef, 0x2e, 0xae, 0x96, 0x57, 0x8c, 0x55, 0x73, 0xaf,
|
||||
0xe4, 0x5b, 0x28, 0x2a, 0x96, 0x4f, 0x63, 0x4e, 0x24, 0x2e, 0x9b, 0x2b, 0xc6, 0xaa, 0xa1, 0x96,
|
||||
0x51, 0xa4, 0x96, 0x97, 0x01, 0x32, 0x29, 0x58, 0xd2, 0xc6, 0xf5, 0xca, 0x8a, 0xb1, 0x6a, 0xef,
|
||||
0x95, 0x7c, 0x5b, 0xcb, 0x4e, 0x48, 0xbc, 0x55, 0x05, 0xb3, 0x47, 0x62, 0xef, 0x7b, 0x03, 0xec,
|
||||
0x6f, 0x72, 0x2a, 0xfa, 0xfb, 0xc9, 0x29, 0x77, 0x5d, 0xa8, 0x48, 0x9e, 0xbe, 0x40, 0x67, 0x4c,
|
||||
0x1f, 0xc7, 0xee, 0x32, 0xd4, 0xbb, 0x54, 0x0a, 0x16, 0x06, 0xb2, 0x9f, 0x52, 0xdc, 0xca, 0xf6,
|
||||
0x41, 0x8b, 0x8e, 0xfb, 0x29, 0x75, 0x3f, 0x84, 0xc5, 0x8c, 0x12, 0x11, 0x76, 0x82, 0x94, 0x08,
|
||||
0xd2, 0xcd, 0xf4, 0x6e, 0x7e, 0x43, 0x0b, 0x8f, 0x50, 0xa6, 0x94, 0x04, 0xcf, 0x93, 0x28, 0x88,
|
||||
0x68, 0xc8, 0xba, 0x24, 0xbe, 0x58, 0xc5, 0x2d, 0x1a, 0x28, 0xdc, 0xd1, 0x32, 0xef, 0x67, 0x03,
|
||||
0x60, 0x9b, 0xc7, 0x79, 0x37, 0x41, 0x6f, 0x2e, 0x81, 0x75, 0xca, 0x68, 0x1c, 0x05, 0x2c, 0x2a,
|
||||
0x3c, 0xaa, 0xe1, 0x7c, 0x3f, 0x72, 0x1f, 0x82, 0x1d, 0x11, 0x49, 0xb4, 0x4b, 0x8a, 0x9c, 0xe6,
|
||||
0xa7, 0x57, 0xd7, 0x26, 0xf8, 0x2f, 0x98, 0xdf, 0x21, 0x92, 0x28, 0x2f, 0x7d, 0x2b, 0x2a, 0x46,
|
||||
0xee, 0x75, 0x68, 0xb2, 0x2c, 0x48, 0x05, 0xeb, 0x12, 0xd1, 0x0f, 0x5e, 0xd0, 0x3e, 0xc6, 0x64,
|
||||
0xf9, 0x0d, 0x96, 0x1d, 0x69, 0xe1, 0xd7, 0xb4, 0xef, 0x5e, 0x01, 0x9b, 0x65, 0x01, 0xc9, 0x25,
|
||||
0xdf, 0xdf, 0xc1, 0x88, 0x2c, 0xdf, 0x62, 0xd9, 0x26, 0xce, 0xbd, 0x2f, 0x07, 0x7e, 0x3e, 0x7e,
|
||||
0x9d, 0x0a, 0xf7, 0x36, 0x54, 0x58, 0x72, 0xca, 0xd1, 0xc7, 0xfa, 0x9b, 0x7e, 0x60, 0x82, 0x8c,
|
||||
0x82, 0xf2, 0x51, 0xd5, 0xdb, 0x02, 0x1b, 0x53, 0x00, 0xed, 0x3f, 0x83, 0x6a, 0x4f, 0x4d, 0x0a,
|
||||
0x80, 0xe5, 0x29, 0x00, 0xe3, 0x69, 0xe3, 0x6b, 0x6d, 0xef, 0x57, 0x03, 0x9a, 0xcf, 0x13, 0x22,
|
||||
0xfa, 0x3e, 0x49, 0xda, 0x1a, 0xe9, 0x0b, 0xa8, 0x87, 0xb8, 0x55, 0x30, 0xbf, 0x43, 0x10, 0x8e,
|
||||
0x18, 0xff, 0x18, 0xca, 0x3c, 0x2d, 0xf8, 0xbc, 0x34, 0xc5, 0xec, 0x30, 0x45, 0x2e, 0xcb, 0x3c,
|
||||
0x1d, 0x39, 0x6d, 0x9e, 0xcb, 0xe9, 0x5f, 0xca, 0xb0, 0xb4, 0xc5, 0xde, 0xad, 0xd7, 0x37, 0x60,
|
||||
0x29, 0xe6, 0xaf, 0xa8, 0x08, 0x58, 0x12, 0xc6, 0x79, 0xc6, 0x7a, 0x3a, 0x25, 0x2c, 0xbf, 0x89,
|
||||
0xe2, 0xfd, 0x81, 0x54, 0x29, 0xe6, 0x69, 0x3a, 0xa1, 0xa8, 0x8f, 0xbe, 0x89, 0xe2, 0x91, 0xe2,
|
||||
0x06, 0xd4, 0x35, 0xa2, 0x0e, 0xb1, 0x32, 0x5f, 0x88, 0x80, 0x36, 0xfa, 0x6a, 0x6f, 0x40, 0x5d,
|
||||
0x6f, 0xa5, 0x11, 0xaa, 0x73, 0x22, 0xa0, 0x0d, 0x8e, 0xbd, 0x3f, 0x0c, 0xa8, 0x6f, 0xf3, 0x6e,
|
||||
0x4a, 0x84, 0x66, 0x69, 0x17, 0x9c, 0x98, 0x9e, 0xca, 0xe0, 0xdc, 0x54, 0x35, 0x95, 0xd9, 0xd8,
|
||||
0xb5, 0xda, 0x87, 0x0b, 0x82, 0xb5, 0x3b, 0x93, 0x48, 0xe5, 0x79, 0x90, 0x96, 0xd0, 0x6e, 0xfb,
|
||||
0xcd, 0x7c, 0x31, 0xe7, 0xc8, 0x17, 0xef, 0x3b, 0x03, 0xac, 0x63, 0x2a, 0xba, 0xef, 0xe4, 0xc4,
|
||||
0xef, 0xc3, 0x02, 0xf2, 0x9a, 0x5d, 0x2c, 0xaf, 0x98, 0xf3, 0x10, 0x5b, 0xa8, 0xab, 0x12, 0x6c,
|
||||
0xe3, 0x9d, 0x41, 0x37, 0xee, 0xa2, 0xfb, 0x06, 0xba, 0x7f, 0x7d, 0x0a, 0xc4, 0x50, 0x53, 0x8f,
|
||||
0x0e, 0x53, 0xcc, 0xfc, 0x5b, 0x50, 0x0d, 0x3b, 0x2c, 0x8e, 0x0a, 0xce, 0xde, 0x9b, 0x62, 0xa8,
|
||||
0x6c, 0x7c, 0xad, 0xe5, 0x2d, 0x43, 0xad, 0xb0, 0x76, 0xeb, 0x50, 0xdb, 0x4f, 0x7a, 0x24, 0x66,
|
||||
0x91, 0x53, 0x72, 0x6b, 0x60, 0x1e, 0x70, 0xe9, 0x18, 0xde, 0x5f, 0x06, 0x80, 0xbe, 0x12, 0xe8,
|
||||
0xd4, 0xbd, 0x31, 0xa7, 0x3e, 0x9a, 0x82, 0x3d, 0x52, 0x2d, 0x86, 0x85, 0x5b, 0x9f, 0x40, 0x45,
|
||||
0x1d, 0xf4, 0x59, 0x5e, 0xa1, 0x92, 0x8a, 0x01, 0xcf, 0xb2, 0xb8, 0xbd, 0xb3, 0x63, 0x40, 0x2d,
|
||||
0xef, 0x1e, 0x58, 0x83, 0xbd, 0x26, 0x83, 0x68, 0x02, 0x3c, 0xe1, 0x6d, 0x16, 0x92, 0x78, 0x33,
|
||||
0x89, 0x1c, 0xc3, 0x5d, 0x04, 0xbb, 0x98, 0x1f, 0x0a, 0xa7, 0xec, 0xfd, 0x69, 0xc0, 0xa2, 0x36,
|
||||
0xdc, 0x14, 0x4c, 0x76, 0x0e, 0xd3, 0xff, 0x7c, 0xf2, 0x0f, 0xc0, 0x22, 0x0a, 0x2a, 0x18, 0xd6,
|
||||
0xa9, 0x6b, 0x53, 0x8c, 0x8b, 0xdd, 0x30, 0xf9, 0x6a, 0xa4, 0xd8, 0x7a, 0x07, 0x16, 0x75, 0xde,
|
||||
0xf3, 0x94, 0x0a, 0x92, 0x44, 0xf3, 0x56, 0xae, 0x06, 0x5a, 0x1d, 0x6a, 0x23, 0xef, 0x27, 0x63,
|
||||
0x50, 0xc0, 0x70, 0x13, 0x3c, 0xb2, 0x01, 0xf5, 0xc6, 0xb9, 0xa8, 0x2f, 0xcf, 0x43, 0xbd, 0xbb,
|
||||
0x36, 0x76, 0xc5, 0xce, 0x0a, 0x55, 0xdd, 0xb3, 0xdf, 0xcb, 0x70, 0x79, 0x82, 0xf2, 0xc7, 0x3d,
|
||||
0x12, 0xbf, 0xbb, 0x5a, 0xfb, 0x7f, 0xf3, 0x5f, 0x94, 0x9c, 0xca, 0xb9, 0x9e, 0xa8, 0xea, 0xb9,
|
||||
0x9e, 0xa8, 0x7f, 0xaa, 0x50, 0x41, 0xae, 0x1e, 0x82, 0x2d, 0xa9, 0xe8, 0x06, 0xf4, 0x75, 0x2a,
|
||||
0x0a, 0xa6, 0xae, 0x4c, 0xc1, 0x18, 0x54, 0x35, 0xd5, 0x7f, 0xc9, 0x41, 0x85, 0x7b, 0x04, 0x90,
|
||||
0xab, 0x43, 0xd0, 0xc6, 0xfa, 0xa8, 0xdf, 0x7f, 0x5b, 0x89, 0x51, 0xdd, 0x59, 0x3e, 0x2c, 0x02,
|
||||
0x1b, 0x50, 0x6f, 0xb1, 0x91, 0xbd, 0x39, 0xf3, 0x98, 0x46, 0xd5, 0x60, 0xaf, 0xe4, 0x43, 0x6b,
|
||||
0x54, 0x46, 0xb6, 0xa1, 0x11, 0xea, 0xd7, 0x43, 0x43, 0xe8, 0x37, 0xec, 0xda, 0xd4, 0x93, 0x1e,
|
||||
0x3e, 0x32, 0x7b, 0x25, 0xbf, 0x1e, 0x8e, 0xbd, 0x39, 0x4f, 0xc1, 0xd1, 0x51, 0x08, 0x95, 0x40,
|
||||
0x1a, 0x48, 0x93, 0xf9, 0xc1, 0xac, 0x58, 0x86, 0xa9, 0xb6, 0x57, 0xf2, 0x9b, 0xf9, 0xe4, 0x43,
|
||||
0x7f, 0x04, 0x17, 0x8a, 0xa8, 0xc6, 0xf0, 0x16, 0x10, 0xcf, 0x9b, 0x19, 0xdb, 0x38, 0xe0, 0x52,
|
||||
0xeb, 0x8d, 0xd6, 0x41, 0xc2, 0x72, 0x81, 0x38, 0xc8, 0xca, 0x80, 0xf6, 0x48, 0x3c, 0x8e, 0x5f,
|
||||
0x43, 0xfc, 0x5b, 0x33, 0xf1, 0xa7, 0x5d, 0x93, 0xbd, 0x92, 0x7f, 0xb9, 0x35, 0xfb, 0x12, 0x8d,
|
||||
0xe2, 0xd0, 0xbb, 0xe2, 0x3e, 0xd6, 0x19, 0x71, 0x0c, 0xcb, 0xc5, 0x28, 0x8e, 0x51, 0x05, 0x79,
|
||||
0x04, 0x80, 0xc9, 0xa7, 0xa1, 0xec, 0x99, 0xe9, 0x32, 0x6c, 0x1a, 0x55, 0xba, 0xf4, 0x86, 0x1d,
|
||||
0xe4, 0xc6, 0xf0, 0x56, 0xa3, 0x3d, 0x9c, 0x71, 0xab, 0x07, 0xe9, 0x12, 0x0e, 0x67, 0x5b, 0x0b,
|
||||
0x50, 0x51, 0xa6, 0xde, 0xdf, 0x06, 0xc0, 0x09, 0x0d, 0x25, 0x17, 0x9b, 0x07, 0x07, 0xcf, 0x8a,
|
||||
0x2e, 0x58, 0x7b, 0xab, 0xbf, 0x28, 0xaa, 0x0b, 0xd6, 0x01, 0x4d, 0xf4, 0xe7, 0xe5, 0xc9, 0xfe,
|
||||
0xfc, 0x3e, 0x40, 0x2a, 0x68, 0xc4, 0x42, 0x22, 0x69, 0x76, 0xd6, 0x23, 0x33, 0xa6, 0xea, 0x7e,
|
||||
0x0e, 0xf0, 0x52, 0x7d, 0x47, 0x74, 0x79, 0xaa, 0xcc, 0x24, 0x62, 0xf8, 0x67, 0xf1, 0xed, 0x97,
|
||||
0xc3, 0xef, 0xcb, 0x0d, 0x58, 0x4a, 0x63, 0x12, 0xd2, 0x0e, 0x8f, 0x23, 0x2a, 0x02, 0x49, 0xda,
|
||||
0x98, 0xad, 0xb6, 0xdf, 0x1c, 0x13, 0x1f, 0x93, 0xb6, 0xf7, 0x9b, 0x01, 0xd6, 0x51, 0x4c, 0x92,
|
||||
0x03, 0x1e, 0x61, 0xab, 0xd6, 0xc3, 0x88, 0x03, 0x92, 0x24, 0xd9, 0x5b, 0x4a, 0xe2, 0x88, 0x17,
|
||||
0x45, 0x9e, 0xb6, 0xd9, 0x4c, 0x92, 0xcc, 0x7d, 0x30, 0x11, 0xed, 0xdb, 0xeb, 0xba, 0x32, 0x1d,
|
||||
0x8b, 0x77, 0x15, 0x1c, 0x9e, 0xcb, 0x34, 0x97, 0xc1, 0x80, 0x4a, 0x45, 0x97, 0xb9, 0x6a, 0xfa,
|
||||
0x4d, 0x2d, 0xff, 0x4a, 0x33, 0x9a, 0xa9, 0x13, 0x4a, 0x78, 0x44, 0x6f, 0xfe, 0x68, 0xc0, 0x82,
|
||||
0x2e, 0x72, 0x93, 0x4f, 0xf1, 0x12, 0xd4, 0x77, 0x05, 0x25, 0x92, 0x8a, 0xe3, 0x0e, 0x49, 0x1c,
|
||||
0xc3, 0x75, 0xa0, 0x51, 0x08, 0x1e, 0xbf, 0xcc, 0x49, 0xec, 0x94, 0xdd, 0x06, 0x58, 0x4f, 0x68,
|
||||
0x96, 0xe1, 0xba, 0x89, 0x6f, 0x35, 0xcd, 0x32, 0xbd, 0x58, 0x71, 0x6d, 0xa8, 0xea, 0x61, 0x55,
|
||||
0xe9, 0x1d, 0x70, 0xa9, 0x67, 0x0b, 0x0a, 0xf8, 0x48, 0xd0, 0x53, 0xf6, 0xfa, 0x29, 0x91, 0x61,
|
||||
0xc7, 0xa9, 0x29, 0xe0, 0x23, 0x9e, 0xc9, 0xa1, 0xc4, 0x52, 0xb6, 0x7a, 0x68, 0xdf, 0xdc, 0x85,
|
||||
0xfa, 0x58, 0xf5, 0x57, 0x2e, 0x3e, 0x4f, 0x5e, 0x24, 0xfc, 0x55, 0xa2, 0x5b, 0x9e, 0xcd, 0x48,
|
||||
0xb5, 0x09, 0x35, 0x30, 0x9f, 0xe5, 0x2d, 0xa7, 0xac, 0x06, 0x4f, 0xf3, 0xd8, 0x31, 0xd5, 0x60,
|
||||
0x87, 0xf5, 0x9c, 0x0a, 0x4a, 0x78, 0xe4, 0x54, 0xb7, 0xee, 0x7c, 0x7b, 0xbb, 0xcd, 0x64, 0x27,
|
||||
0x6f, 0xad, 0x85, 0xbc, 0xbb, 0xae, 0xc9, 0xbc, 0xc5, 0x78, 0x31, 0x5a, 0x67, 0x89, 0xa4, 0x22,
|
||||
0x21, 0xf1, 0x3a, 0xf2, 0xbb, 0xae, 0xf8, 0x4d, 0x5b, 0xad, 0x05, 0x9c, 0xdd, 0xf9, 0x37, 0x00,
|
||||
0x00, 0xff, 0xff, 0xc8, 0xcd, 0x73, 0x91, 0x98, 0x0f, 0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -289,6 +289,16 @@ func isSameOrder(opStr1, opStr2 string) bool {
|
|||
return isLess1 == isLess2
|
||||
}
|
||||
|
||||
var opMap = map[planpb.OpType]string{
|
||||
planpb.OpType_Invalid: "invalid",
|
||||
planpb.OpType_GreaterThan: ">",
|
||||
planpb.OpType_GreaterEqual: ">=",
|
||||
planpb.OpType_LessThan: "<",
|
||||
planpb.OpType_LessEqual: "<=",
|
||||
planpb.OpType_Equal: "==",
|
||||
planpb.OpType_NotEqual: "!=",
|
||||
}
|
||||
|
||||
func getCompareOpType(opStr string, reverse bool) (op planpb.OpType) {
|
||||
switch opStr {
|
||||
case ">":
|
||||
|
@ -513,16 +523,23 @@ func (pc *parserContext) handleCmpExpr(node *ant_ast.BinaryNode) (*planpb.Expr,
|
|||
|
||||
func (pc *parserContext) handleBinaryArithCmpExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
|
||||
leftNode, funcNodeLeft := node.Left.(*ant_ast.FunctionNode)
|
||||
_, funcNodeRight := node.Right.(*ant_ast.FunctionNode)
|
||||
rightNode, funcNodeRight := node.Right.(*ant_ast.FunctionNode)
|
||||
|
||||
if funcNodeRight {
|
||||
return nil, fmt.Errorf("right node as a function is not supported yet")
|
||||
} else if !funcNodeLeft {
|
||||
// Both left and right are not function nodes, pass to createCmpExpr
|
||||
return pc.createCmpExpr(node.Left, node.Right, node.Operator)
|
||||
} else {
|
||||
if funcNodeLeft && funcNodeRight {
|
||||
return nil, fmt.Errorf("left and right are both expression are not supported")
|
||||
} else if funcNodeRight {
|
||||
// Only the right node is a function node
|
||||
op := getCompareOpType(node.Operator, true)
|
||||
if op == planpb.OpType_Invalid {
|
||||
return nil, fmt.Errorf("invalid right expression")
|
||||
}
|
||||
return pc.createBinaryArithOpEvalExpr(rightNode, &node.Left, opMap[op])
|
||||
} else if funcNodeLeft {
|
||||
// Only the left node is a function node
|
||||
return pc.createBinaryArithOpEvalExpr(leftNode, &node.Right, node.Operator)
|
||||
} else {
|
||||
// Both left and right are not function nodes, pass to createCmpExpr
|
||||
return pc.createCmpExpr(node.Left, node.Right, node.Operator)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,9 +704,10 @@ func (pc *parserContext) handleMultiCmpExpr(node *ant_ast.BinaryNode) (*planpb.E
|
|||
}
|
||||
|
||||
func (pc *parserContext) handleBinaryExpr(node *ant_ast.BinaryNode) (*planpb.Expr, error) {
|
||||
_, arithExpr := node.Left.(*ant_ast.FunctionNode)
|
||||
_, leftArithExpr := node.Left.(*ant_ast.FunctionNode)
|
||||
_, rightArithExpr := node.Right.(*ant_ast.FunctionNode)
|
||||
|
||||
if arithExpr {
|
||||
if leftArithExpr || rightArithExpr {
|
||||
return pc.handleBinaryArithCmpExpr(node)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/milvus-io/milvus/internal/parser/planparserv2"
|
||||
|
||||
ant_ast "github.com/antonmedv/expr/ast"
|
||||
ant_parser "github.com/antonmedv/expr/parser"
|
||||
|
||||
|
@ -55,6 +57,85 @@ func newTestSchema() *schemapb.CollectionSchema {
|
|||
}
|
||||
}
|
||||
|
||||
func assertValidExpr(t *testing.T, schema *typeutil.SchemaHelper, exprStr string) {
|
||||
// fmt.Println("expr: ", exprStr)
|
||||
|
||||
_, err := parseExpr(schema, exprStr)
|
||||
assert.Nil(t, err, exprStr)
|
||||
|
||||
// fmt.Println("AST1:")
|
||||
// planparserv2.ShowExpr(expr1)
|
||||
}
|
||||
|
||||
func assertValidExprV2(t *testing.T, schema *typeutil.SchemaHelper, exprStr string) {
|
||||
expr1, err := parseExpr(schema, exprStr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
expr2, err := planparserv2.ParseExpr(schema, exprStr)
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !planparserv2.CheckIdentical(expr1, expr2) {
|
||||
fmt.Println("expr: ", exprStr)
|
||||
|
||||
fmt.Println("AST1:")
|
||||
planparserv2.ShowExpr(expr1)
|
||||
|
||||
fmt.Println("AST2:")
|
||||
planparserv2.ShowExpr(expr2)
|
||||
|
||||
t.Errorf("parsed asts are not identical")
|
||||
}
|
||||
}
|
||||
|
||||
func assertInvalidExpr(t *testing.T, schema *typeutil.SchemaHelper, exprStr string) {
|
||||
// fmt.Println("expr: ", exprStr)
|
||||
|
||||
_, err := parseExpr(schema, exprStr)
|
||||
assert.Error(t, err, exprStr)
|
||||
|
||||
_, err = planparserv2.ParseExpr(schema, exprStr)
|
||||
assert.Error(t, err, exprStr)
|
||||
}
|
||||
|
||||
func assertValidSearchPlan(t *testing.T, schema *schemapb.CollectionSchema, exprStr string, vectorFieldName string, queryInfo *planpb.QueryInfo) {
|
||||
_, err := createQueryPlan(schema, exprStr, vectorFieldName, queryInfo)
|
||||
assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func assertValidSearchPlanV2(t *testing.T, schema *schemapb.CollectionSchema, exprStr string, vectorFieldName string, queryInfo *planpb.QueryInfo) {
|
||||
planProto1, err := createQueryPlan(schema, exprStr, vectorFieldName, queryInfo)
|
||||
assert.Nil(t, err)
|
||||
|
||||
planProto2, err := planparserv2.CreateSearchPlan(schema, exprStr, vectorFieldName, queryInfo)
|
||||
assert.Nil(t, err)
|
||||
|
||||
expr1 := planProto1.GetVectorAnns().GetPredicates()
|
||||
assert.NotNil(t, expr1)
|
||||
|
||||
expr2 := planProto2.GetVectorAnns().GetPredicates()
|
||||
assert.NotNil(t, expr2)
|
||||
|
||||
if !planparserv2.CheckIdentical(expr1, expr2) {
|
||||
fmt.Println("expr: ", exprStr)
|
||||
|
||||
fmt.Println("AST1:")
|
||||
planparserv2.ShowExpr(expr1)
|
||||
|
||||
fmt.Println("AST2:")
|
||||
planparserv2.ShowExpr(expr2)
|
||||
|
||||
t.Errorf("parsed asts are not identical")
|
||||
}
|
||||
}
|
||||
|
||||
func assertInvalidSearchPlan(t *testing.T, schema *schemapb.CollectionSchema, exprStr string, vectorFieldName string, queryInfo *planpb.QueryInfo) {
|
||||
_, err := createQueryPlan(schema, exprStr, vectorFieldName, queryInfo)
|
||||
assert.Error(t, err, exprStr)
|
||||
|
||||
_, err = planparserv2.CreateSearchPlan(schema, exprStr, vectorFieldName, queryInfo)
|
||||
assert.Error(t, err, exprStr)
|
||||
}
|
||||
|
||||
func TestParseExpr_Naive(t *testing.T) {
|
||||
schemaPb := newTestSchema()
|
||||
schema, err := typeutil.CreateSchemaHelper(schemaPb)
|
||||
|
@ -67,14 +148,19 @@ func TestParseExpr_Naive(t *testing.T) {
|
|||
"FloatField > +1.0",
|
||||
"FloatField > -1.0",
|
||||
`VarCharField > "str"`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidExprV2(t, schema, exprStr)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("test string unary", func(t *testing.T) {
|
||||
exprStrs := []string{
|
||||
`VarCharField startsWith "str"`,
|
||||
`VarCharField endsWith "str"`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
exprProto, err := parseExpr(schema, exprStr)
|
||||
assert.Nil(t, err)
|
||||
str := proto.MarshalTextString(exprProto)
|
||||
println(str)
|
||||
assertValidExpr(t, schema, exprStr)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -85,9 +171,7 @@ func TestParseExpr_Naive(t *testing.T) {
|
|||
`VarCharField > -aa`,
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
exprProto, err := parseExpr(schema, exprStr)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, exprProto)
|
||||
assertInvalidExpr(t, schema, exprStr)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -122,10 +206,7 @@ func TestParseExpr_Naive(t *testing.T) {
|
|||
"FloatField > 1.0 ** 2.0",
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
exprProto, err := parseExpr(schema, exprStr)
|
||||
assert.Nil(t, err)
|
||||
str := proto.MarshalTextString(exprProto)
|
||||
println(str)
|
||||
assertValidExprV2(t, schema, exprStr)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -156,9 +237,7 @@ func TestParseExpr_Naive(t *testing.T) {
|
|||
"FloatField > aa ** 2.0",
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
exprProto, err := parseExpr(schema, exprStr)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, exprProto)
|
||||
assertInvalidExpr(t, schema, exprStr)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -184,10 +263,7 @@ func TestParseExpr_Naive(t *testing.T) {
|
|||
"Int64Field % 7 == 5",
|
||||
}
|
||||
for _, exprStr := range exprStrs {
|
||||
exprProto, err := parseExpr(schema, exprStr)
|
||||
assert.Nil(t, err)
|
||||
str := proto.MarshalTextString(exprProto)
|
||||
println(str)
|
||||
assertValidExprV2(t, schema, exprStr)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -233,11 +309,8 @@ func TestParsePlanNode_Naive(t *testing.T) {
|
|||
"DoubleField in [1.0, 2, 3] && Int64Field < 3 or Int64Field > 2",
|
||||
`not (VarCharField > "str")`,
|
||||
`not ("str" > VarCharField)`,
|
||||
`not (VarCharField startsWith "str")`,
|
||||
`not (VarCharField endsWith "str")`,
|
||||
`VarCharField in ["term0", "term1", "term2"]`,
|
||||
`VarCharField < "str3" and (VarCharField > "str2" || VarCharField == "str1")`,
|
||||
`VarCharField < "str3" and (VarCharField startsWith "str2" || VarCharField endsWith "str1")`,
|
||||
`DoubleField in [1.0, 2, 3] && VarCharField < "str3" or Int64Field > 2`,
|
||||
}
|
||||
|
||||
|
@ -248,16 +321,18 @@ func TestParsePlanNode_Naive(t *testing.T) {
|
|||
SearchParams: "{\"nprobe\": 10}",
|
||||
}
|
||||
|
||||
// Note: use pointer to string to represent nullable string
|
||||
// TODO: change it to better solution
|
||||
for offset, exprStr := range exprStrs {
|
||||
fmt.Printf("case %d: %s\n", offset, exprStr)
|
||||
planProto, err := createQueryPlan(schema, exprStr, "FloatVectorField", queryInfo)
|
||||
assert.Nil(t, err)
|
||||
dbgStr := proto.MarshalTextString(planProto)
|
||||
println(dbgStr)
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidSearchPlanV2(t, schema, exprStr, "FloatVectorField", queryInfo)
|
||||
}
|
||||
|
||||
stringFuncs := []string{
|
||||
`not (VarCharField startsWith "str")`,
|
||||
`not (VarCharField endsWith "str")`,
|
||||
`VarCharField < "str3" and (VarCharField startsWith "str2" || VarCharField endsWith "str1")`,
|
||||
}
|
||||
for _, exprStr := range stringFuncs {
|
||||
assertValidSearchPlan(t, schema, exprStr, "FloatVectorField", queryInfo)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExternalParser(t *testing.T) {
|
||||
|
@ -299,19 +374,15 @@ func TestExprPlan_Str(t *testing.T) {
|
|||
"age not in [1, 2, 3]",
|
||||
}
|
||||
|
||||
for offset, exprStr := range exprStrs {
|
||||
fmt.Printf("case %d: %s\n", offset, exprStr)
|
||||
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
|
||||
assert.Nil(t, err)
|
||||
dbgStr := proto.MarshalTextString(planProto)
|
||||
println(dbgStr)
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidSearchPlanV2(t, schema, exprStr, "fakevec", queryInfo)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExprMultiRange_Str(t *testing.T) {
|
||||
exprStrs := []string{
|
||||
"3 < FloatN < 4.0",
|
||||
"3 < age1 < 5 < age2 < 7 < FloatN < 9.0 < FloatN2",
|
||||
// "3 < age1 < 5 < age2 < 7 < FloatN < 9.0 < FloatN2", // no need to support this, ambiguous.
|
||||
"1 + 1 < age1 < 2 * 2",
|
||||
"1 - 1 < age1 < 3 / 2",
|
||||
"1.0 - 1 < FloatN < 3 / 2",
|
||||
|
@ -351,26 +422,18 @@ func TestExprMultiRange_Str(t *testing.T) {
|
|||
SearchParams: "{\"nprobe\": 10}",
|
||||
}
|
||||
|
||||
for offset, exprStr := range exprStrs {
|
||||
fmt.Printf("case %d: %s\n", offset, exprStr)
|
||||
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
|
||||
assert.Nil(t, err)
|
||||
dbgStr := proto.MarshalTextString(planProto)
|
||||
println(dbgStr)
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidSearchPlanV2(t, schema, exprStr, "fakevec", queryInfo)
|
||||
}
|
||||
for offset, exprStr := range invalidExprs {
|
||||
fmt.Printf("invalid case %d: %s\n", offset, exprStr)
|
||||
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
|
||||
assert.Error(t, err)
|
||||
dbgStr := proto.MarshalTextString(planProto)
|
||||
println(dbgStr)
|
||||
for _, exprStr := range invalidExprs {
|
||||
assertInvalidSearchPlan(t, schema, exprStr, "fakevec", queryInfo)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExprFieldCompare_Str(t *testing.T) {
|
||||
exprStrs := []string{
|
||||
"age1 < age2",
|
||||
"3 < age1 <= age2 < 4",
|
||||
// "3 < age1 <= age2 < 4", // no need to support this, ambiguous.
|
||||
}
|
||||
|
||||
fields := []*schemapb.FieldSchema{
|
||||
|
@ -393,12 +456,8 @@ func TestExprFieldCompare_Str(t *testing.T) {
|
|||
SearchParams: "{\"nprobe\": 10}",
|
||||
}
|
||||
|
||||
for offset, exprStr := range exprStrs {
|
||||
fmt.Printf("case %d: %s\n", offset, exprStr)
|
||||
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
|
||||
assert.Nil(t, err)
|
||||
dbgStr := proto.MarshalTextString(planProto)
|
||||
println(dbgStr)
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidSearchPlanV2(t, schema, exprStr, "fakevec", queryInfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -418,6 +477,8 @@ func TestExprBinaryArithOp_Str(t *testing.T) {
|
|||
"(age1 * 4) != 9",
|
||||
"(5 * FloatN) != 0",
|
||||
"(9 * FloatN) != 0",
|
||||
// Functional nodes at the right can be reversed
|
||||
"0 == (age1 + 3)",
|
||||
}
|
||||
|
||||
unsupportedExprStrs := []string{
|
||||
|
@ -426,8 +487,6 @@ func TestExprBinaryArithOp_Str(t *testing.T) {
|
|||
"(age1 + 2) >= 4",
|
||||
"(age1 + 2) < 4",
|
||||
"(age1 + 2) <= 4",
|
||||
// Functional nodes at the right of the comparison are not allowed
|
||||
"0 == (age1 + 3)",
|
||||
// Field as the right operand for -, /, and % operators are not supported
|
||||
"(10 - age1) == 0",
|
||||
"(20 / age1) == 0",
|
||||
|
@ -459,19 +518,12 @@ func TestExprBinaryArithOp_Str(t *testing.T) {
|
|||
SearchParams: "{\"nprobe\": 10}",
|
||||
}
|
||||
|
||||
for offset, exprStr := range exprStrs {
|
||||
fmt.Printf("case %d: %s\n", offset, exprStr)
|
||||
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
|
||||
assert.Nil(t, err)
|
||||
dbgStr := proto.MarshalTextString(planProto)
|
||||
println(dbgStr)
|
||||
for _, exprStr := range exprStrs {
|
||||
assertValidSearchPlanV2(t, schema, exprStr, "fakevec", queryInfo)
|
||||
}
|
||||
for offset, exprStr := range unsupportedExprStrs {
|
||||
fmt.Printf("case %d: %s\n", offset, exprStr)
|
||||
planProto, err := createQueryPlan(schema, exprStr, "fakevec", queryInfo)
|
||||
assert.Error(t, err)
|
||||
dbgStr := proto.MarshalTextString(planProto)
|
||||
println(dbgStr)
|
||||
|
||||
for _, exprStr := range unsupportedExprStrs {
|
||||
assertInvalidSearchPlan(t, schema, exprStr, "fakevec", queryInfo)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -546,3 +598,44 @@ func TestPlanParseAPIs(t *testing.T) {
|
|||
assert.Nil(t, parseBoolNode(&nodeRaw4))
|
||||
})
|
||||
}
|
||||
|
||||
func Test_CheckIdentical(t *testing.T) {
|
||||
schema := newTestSchema()
|
||||
helper, err := typeutil.CreateSchemaHelper(schema)
|
||||
assert.NoError(t, err)
|
||||
|
||||
n := 5000
|
||||
int64s := generateInt64Array(n)
|
||||
largeIntTermExpr := `Int64Field in [`
|
||||
largeFloatTermExpr := `FloatField in [`
|
||||
for _, i := range int64s[:n-1] {
|
||||
largeIntTermExpr += fmt.Sprintf("%d, ", i)
|
||||
largeFloatTermExpr += fmt.Sprintf("%d, ", i)
|
||||
}
|
||||
largeIntTermExpr += fmt.Sprintf("%d]", int64s[n-1])
|
||||
largeFloatTermExpr += fmt.Sprintf("%d]", int64s[n-1])
|
||||
|
||||
// cases in regression.
|
||||
inputs := []string{
|
||||
"Int64Field > 0",
|
||||
"(Int64Field > 0 && Int64Field < 400) or (Int64Field > 500 && Int64Field < 1000)",
|
||||
"Int64Field not in [1, 2, 3]",
|
||||
"Int64Field in [1, 2, 3] and FloatField != 2",
|
||||
"Int64Field == 0 || Int64Field == 1 || Int64Field == 2",
|
||||
"0 < Int64Field < 400",
|
||||
"500 <= Int64Field < 1000",
|
||||
"200+300 < Int64Field <= 500+500",
|
||||
"Int32Field != Int64Field",
|
||||
"Int64Field not in []",
|
||||
largeIntTermExpr,
|
||||
largeFloatTermExpr,
|
||||
}
|
||||
for _, input := range inputs {
|
||||
// fmt.Println("expr: ", input)
|
||||
expr1, err := parseExpr(helper, input)
|
||||
assert.NoError(t, err)
|
||||
expr2, err := planparserv2.ParseExpr(helper, input)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, planparserv2.CheckIdentical(expr1, expr2))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -238,6 +238,11 @@ func IsFloatingType(dataType schemapb.DataType) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// IsArithmetic returns true if input is of arithmetic type, otherwise false.
|
||||
func IsArithmetic(dataType schemapb.DataType) bool {
|
||||
return IsIntegerType(dataType) || IsFloatingType(dataType)
|
||||
}
|
||||
|
||||
// IsBoolType returns true if input is a bool type, otherwise false
|
||||
func IsBoolType(dataType schemapb.DataType) bool {
|
||||
switch dataType {
|
||||
|
@ -251,7 +256,7 @@ func IsBoolType(dataType schemapb.DataType) bool {
|
|||
// IsStringType returns true if input is a varChar type, otherwise false
|
||||
func IsStringType(dataType schemapb.DataType) bool {
|
||||
switch dataType {
|
||||
case schemapb.DataType_VarChar:
|
||||
case schemapb.DataType_String, schemapb.DataType_VarChar:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
|
||||
package gorules
|
||||
|
||||
import "github.com/quasilyte/go-ruleguard/dsl/fluent"
|
||||
import (
|
||||
"github.com/quasilyte/go-ruleguard/dsl/fluent"
|
||||
)
|
||||
|
||||
// This is a collection of rules for ruleguard: https://github.com/quasilyte/go-ruleguard
|
||||
|
||||
|
@ -222,14 +224,14 @@ func floateq(m fluent.Matcher) {
|
|||
"$x == $y",
|
||||
"$x != $y",
|
||||
).
|
||||
Where(m["x"].Type.Is("float32") && !m["x"].Const && !m["y"].Text.Matches("0(.0+)?")).
|
||||
Where(m["x"].Type.Is("float32") && !m["x"].Const && !m["y"].Text.Matches("0(.0+)?") && !m.File().Name.Matches("floating_comparision.go")).
|
||||
Report("floating point tested for equality")
|
||||
|
||||
m.Match(
|
||||
"$x == $y",
|
||||
"$x != $y",
|
||||
).
|
||||
Where(m["x"].Type.Is("float64") && !m["x"].Const && !m["y"].Text.Matches("0(.0+)?")).
|
||||
Where(m["x"].Type.Is("float64") && !m["x"].Const && !m["y"].Text.Matches("0(.0+)?") && !m.File().Name.Matches("floating_comparision.go")).
|
||||
Report("floating point tested for equality")
|
||||
|
||||
m.Match("switch $x { $*_ }", "switch $*_; $x { $*_ }").
|
||||
|
|
|
@ -27,10 +27,10 @@ echo "Running unittest under ./internal"
|
|||
if [[ $(uname -s) == "Darwin" && "$(uname -m)" == "arm64" ]]; then
|
||||
APPLE_SILICON_FLAG="-tags dynamic"
|
||||
fi
|
||||
for d in $(go list ./internal/... | grep -v -e vendor -e kafka); do
|
||||
for d in $(go list ./internal/... | grep -v -e vendor -e kafka -e planparserv2/generated); do
|
||||
go test -race ${APPLE_SILICON_FLAG} -v -coverpkg=./... -coverprofile=profile.out -covermode=atomic "$d"
|
||||
if [ -f profile.out ]; then
|
||||
grep -v kafka profile.out | sed '1d' >> ${FILE_COVERAGE_INFO}
|
||||
grep -v kafka profile.out | grep -v planparserv2/generated | sed '1d' >> ${FILE_COVERAGE_INFO}
|
||||
rm profile.out
|
||||
fi
|
||||
done
|
||||
|
|
Loading…
Reference in New Issue