github.com/influxdata/influxdb/v2@v2.7.6/predicate/parser_test.go (about) 1 package predicate 2 3 import ( 4 "strings" 5 "testing" 6 7 "github.com/google/go-cmp/cmp" 8 "github.com/influxdata/influxdb/v2" 9 "github.com/influxdata/influxdb/v2/kit/platform/errors" 10 influxtesting "github.com/influxdata/influxdb/v2/testing" 11 "github.com/influxdata/influxql" 12 ) 13 14 func TestParseNode(t *testing.T) { 15 cases := []struct { 16 str string 17 node Node 18 err error 19 }{ 20 { 21 str: `abc=opq`, 22 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "opq"}}, 23 }, 24 { 25 str: `abc=opq and gender="male"`, 26 node: LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 27 TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "opq"}}, 28 TagRuleNode{Tag: influxdb.Tag{Key: "gender", Value: "male"}}, 29 }}, 30 }, 31 { 32 str: ` abc="opq" AND gender="male" AND temp=1123`, 33 node: LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 34 LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 35 TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "opq"}}, 36 TagRuleNode{Tag: influxdb.Tag{Key: "gender", Value: "male"}}, 37 }}, 38 TagRuleNode{Tag: influxdb.Tag{Key: "temp", Value: "1123"}}, 39 }}, 40 }, 41 { 42 str: ` abc="opq" Or gender="male" OR temp=1123`, 43 err: &errors.Error{ 44 Code: errors.EInvalid, 45 Msg: "the logical operator OR is not supported yet at position 11", 46 }, 47 }, 48 { 49 str: ` (t1="v1" and t2="v2") and (t3=v3 and (t4=v4 and t5=v5 and t6=v6))`, 50 node: LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 51 LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 52 TagRuleNode{Tag: influxdb.Tag{Key: "t1", Value: "v1"}}, 53 TagRuleNode{Tag: influxdb.Tag{Key: "t2", Value: "v2"}}, 54 }}, 55 LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 56 TagRuleNode{Tag: influxdb.Tag{Key: "t3", Value: "v3"}}, 57 LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 58 LogicalNode{Operator: LogicalAnd, Children: [2]Node{ 59 TagRuleNode{Tag: influxdb.Tag{Key: "t4", Value: "v4"}}, 60 TagRuleNode{Tag: influxdb.Tag{Key: "t5", Value: "v5"}}, 61 }}, 62 TagRuleNode{Tag: influxdb.Tag{Key: "t6", Value: "v6"}}, 63 }}, 64 }}, 65 }}, 66 }, 67 { 68 str: ` (t1="v1" and t2="v2") and (`, 69 err: &errors.Error{ 70 Code: errors.EInvalid, 71 Msg: "extra ( seen", 72 }, 73 }, 74 { 75 str: ` (t1="v1" and t2="v2"))`, 76 err: &errors.Error{ 77 Code: errors.EInvalid, 78 Msg: "extra ) seen", 79 }, 80 }, 81 } 82 for _, c := range cases { 83 node, err := Parse(c.str) 84 influxtesting.ErrorsEqual(t, err, c.err) 85 if c.err == nil { 86 if diff := cmp.Diff(node, c.node); diff != "" { 87 t.Errorf("tag rule mismatch:\n %s", diff) 88 } 89 } 90 } 91 } 92 93 func TestParseTagRule(t *testing.T) { 94 cases := []struct { 95 str string 96 node TagRuleNode 97 err error 98 }{ 99 { 100 str: ` abc = "opq"`, 101 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "opq"}}, 102 }, 103 { 104 str: `abc=0x1231`, 105 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "0x1231"}}, 106 }, 107 { 108 str: `abc=2d`, 109 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "2d"}}, 110 }, 111 { 112 str: `abc=-5i`, 113 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "-5i"}}, 114 }, 115 { 116 str: `abc= -1221`, 117 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "-1221"}}, 118 }, 119 { 120 str: ` abc != "opq"`, 121 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "opq"}, Operator: influxdb.NotEqual}, 122 }, 123 { 124 str: `abc=123`, 125 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "123"}, Operator: influxdb.Equal}, 126 }, 127 { 128 str: `abc=true`, 129 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "true"}, Operator: influxdb.Equal}, 130 }, 131 { 132 str: `abc=false`, 133 node: TagRuleNode{Tag: influxdb.Tag{Key: "abc", Value: "false"}, Operator: influxdb.Equal}, 134 }, 135 { 136 str: `abc!~/^payments\./`, 137 err: &errors.Error{ 138 Code: errors.EInvalid, 139 Msg: `operator: "!~" at position: 3 is not supported yet`, 140 }, 141 }, 142 { 143 str: `abc=~/^payments\./`, 144 err: &errors.Error{ 145 Code: errors.EInvalid, 146 Msg: `operator: "=~" at position: 3 is not supported yet`, 147 }, 148 }, 149 { 150 str: `abc>1000`, 151 err: &errors.Error{ 152 Code: errors.EInvalid, 153 Msg: `invalid operator ">" at position: 3`, 154 }, 155 }, 156 } 157 for _, c := range cases { 158 p := new(parser) 159 p.sc = influxql.NewScanner(strings.NewReader(c.str)) 160 tr, err := p.parseTagRuleNode() 161 influxtesting.ErrorsEqual(t, err, c.err) 162 if c.err == nil { 163 if diff := cmp.Diff(tr, c.node); diff != "" { 164 t.Errorf("tag rule mismatch:\n %s", diff) 165 } 166 } 167 } 168 }