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  }