github.com/GuanceCloud/cliutils@v1.1.21/filter/ast.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package filter
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/json"
    11  	"fmt"
    12  	"reflect"
    13  	"regexp"
    14  	"strings"
    15  	"time"
    16  )
    17  
    18  const (
    19  	Nil = "nil"
    20  )
    21  
    22  type Value interface {
    23  	Type() ValueType
    24  	String() string
    25  }
    26  
    27  type ValueType string
    28  
    29  //
    30  // Node.
    31  //
    32  
    33  type Node interface {
    34  	String() string
    35  	Pos() *PositionRange
    36  }
    37  
    38  type CascadeFunctions struct {
    39  	Funcs []*FuncExpr `json:"function_list,omitempty"`
    40  }
    41  
    42  func (n *CascadeFunctions) Pos() *PositionRange { return nil }
    43  func (n *CascadeFunctions) String() string {
    44  	arr := []string{}
    45  	for _, f := range n.Funcs {
    46  		arr = append(arr, f.String())
    47  	}
    48  
    49  	return strings.Join(arr, ".")
    50  }
    51  
    52  type Anonymous struct{}
    53  
    54  func (n *Anonymous) Pos() *PositionRange { return nil }
    55  func (n *Anonymous) String() string {
    56  	return ""
    57  }
    58  
    59  type AttrExpr struct {
    60  	Obj  Node `json:"object,omitempty"`
    61  	Attr Node `json:"attr,omitempty"`
    62  }
    63  
    64  func (n *AttrExpr) Pos() *PositionRange { return nil }
    65  func (n *AttrExpr) String() string {
    66  	return fmt.Sprintf("%s.%s", n.Obj.String(), n.Attr.String())
    67  }
    68  
    69  type Star struct{}
    70  
    71  func (n *Star) MarshalJSON() ([]byte, error) {
    72  	return []byte(`"*"`), nil
    73  }
    74  
    75  func (n *Star) Pos() *PositionRange { return nil }
    76  func (n *Star) String() string {
    77  	return "*"
    78  }
    79  
    80  type Stmts []Node
    81  
    82  func (n Stmts) Pos() *PositionRange { return nil }
    83  func (n Stmts) String() string {
    84  	arr := []string{}
    85  	for _, n := range n {
    86  		arr = append(arr, n.String())
    87  	}
    88  
    89  	return strings.Join(arr, "; ")
    90  }
    91  
    92  type BoolLiteral struct {
    93  	Val bool `json:"val,omitempty"`
    94  }
    95  
    96  func (n *BoolLiteral) Pos() *PositionRange { return nil }
    97  func (n *BoolLiteral) String() string {
    98  	return fmt.Sprintf("%v", n.Val)
    99  }
   100  
   101  type NilLiteral struct{}
   102  
   103  func (n *NilLiteral) Pos() *PositionRange { return nil }
   104  func (n *NilLiteral) String() string {
   105  	return Nil
   106  }
   107  
   108  type Limit struct {
   109  	Limit int64 `json:"val,omitempty"`
   110  }
   111  
   112  func (n *Limit) Pos() *PositionRange { return nil }
   113  func (n *Limit) String() string {
   114  	return fmt.Sprintf("LIMIT %d", n.Limit)
   115  }
   116  
   117  type SLimit struct {
   118  	SLimit int64 `json:"val,omitempty"`
   119  }
   120  
   121  func (n *SLimit) Pos() *PositionRange { return nil }
   122  func (n *SLimit) String() string {
   123  	return fmt.Sprintf("SLIMIT %d", n.SLimit)
   124  }
   125  
   126  type Offset struct {
   127  	Offset int64 `json:"val,omitempty"`
   128  }
   129  
   130  func (n *Offset) Pos() *PositionRange { return nil }
   131  func (n *Offset) String() string {
   132  	return fmt.Sprintf("OFFSET %d", n.Offset)
   133  }
   134  
   135  type SOffset struct {
   136  	SOffset int64 `json:"val,omitempty"`
   137  }
   138  
   139  func (n *SOffset) Pos() *PositionRange { return nil }
   140  func (n *SOffset) String() string {
   141  	return fmt.Sprintf("SOFFSET %d", n.SOffset)
   142  }
   143  
   144  type OrderType int
   145  
   146  const (
   147  	OrderAsc OrderType = iota
   148  	OrderDesc
   149  )
   150  
   151  type OrderByElem struct {
   152  	Column string    `json:"-"`
   153  	Opt    OrderType `json:"-"`
   154  }
   155  
   156  func (n *OrderByElem) Pos() *PositionRange { return nil }
   157  func (n *OrderByElem) String() string {
   158  	if n.Opt == OrderDesc {
   159  		return fmt.Sprintf("%s DESC", n.Column)
   160  	}
   161  	return fmt.Sprintf("%s ASC", n.Column)
   162  }
   163  
   164  func (n *OrderByElem) MarshalJSON() ([]byte, error) {
   165  	b, err := json.Marshal(n.Column)
   166  	if err != nil {
   167  		return nil, err
   168  	}
   169  
   170  	const output = `{"column":%s, "opt":"%s"}`
   171  
   172  	switch n.Opt {
   173  	case OrderAsc:
   174  		return []byte(fmt.Sprintf(output, b, "asc")), nil
   175  	case OrderDesc:
   176  		return []byte(fmt.Sprintf(output, b, "desc")), nil
   177  	}
   178  	return []byte(`""`), nil
   179  }
   180  
   181  type OrderBy struct {
   182  	List NodeList
   183  }
   184  
   185  func (n *OrderBy) Pos() *PositionRange { return nil }
   186  func (n *OrderBy) String() string {
   187  	var arr []string
   188  	for _, elem := range n.List {
   189  		arr = append(arr, elem.String())
   190  	}
   191  	return fmt.Sprintf("ORDER BY %s", strings.Join(arr, ", "))
   192  }
   193  
   194  type GroupBy struct {
   195  	List NodeList `json:"val_list,omitempty"`
   196  }
   197  
   198  func (n *GroupBy) Pos() *PositionRange { return nil }
   199  func (n *GroupBy) String() string {
   200  	return fmt.Sprintf("BY %s", n.List.String())
   201  }
   202  
   203  func (n *GroupBy) ColumnList() []string {
   204  	var res []string
   205  	for _, node := range n.List {
   206  		res = append(res, node.String())
   207  	}
   208  	return res
   209  }
   210  
   211  type TimeZone struct {
   212  	Input    string `json:"input,omitempty"`
   213  	TimeZone string `json:"-"`
   214  }
   215  
   216  func (n *TimeZone) Pos() *PositionRange { return nil }
   217  func (n *TimeZone) String() string {
   218  	return fmt.Sprintf(`tz("%s")`, n.Input)
   219  }
   220  
   221  type NodeList []Node
   222  
   223  func (n NodeList) Pos() *PositionRange { return nil }
   224  func (n NodeList) String() string {
   225  	arr := []string{}
   226  	for _, arg := range n {
   227  		arr = append(arr, arg.String())
   228  	}
   229  	return "[" + strings.Join(arr, ", ") + "]"
   230  }
   231  
   232  type FuncArg struct {
   233  	ArgName string `json:"name,omitempty"`
   234  	ArgVal  Node   `json:"val,omitempty"`
   235  }
   236  
   237  func (n *FuncArg) Pos() *PositionRange { return nil }
   238  func (n *FuncArg) String() string {
   239  	if n.ArgVal != nil {
   240  		return fmt.Sprintf("%s=%s", n.ArgName, n.ArgVal.String())
   241  	} else {
   242  		return n.ArgName
   243  	}
   244  }
   245  
   246  type FuncArgList []Node
   247  
   248  func (n FuncArgList) Pos() *PositionRange { return nil }
   249  func (n FuncArgList) String() string {
   250  	arr := []string{}
   251  	for _, x := range n {
   252  		arr = append(arr, x.String())
   253  	}
   254  	return "[" + strings.Join(arr, ", ") + "]"
   255  }
   256  
   257  func getFuncArgList(nl NodeList) FuncArgList {
   258  	var res FuncArgList
   259  	for _, x := range nl {
   260  		res = append(res, x)
   261  	}
   262  	return res
   263  }
   264  
   265  // SearchAfter 深度分页.
   266  type SearchAfter struct {
   267  	Vals []interface{} `json:"vals,omitempty"`
   268  }
   269  
   270  // Pos pos.
   271  func (sa *SearchAfter) Pos() *PositionRange { return nil }
   272  
   273  // String string.
   274  func (sa *SearchAfter) String() string {
   275  	return fmt.Sprintf("%v", sa.Vals)
   276  }
   277  
   278  const (
   279  	FillNil int = iota + 1
   280  	FillInt
   281  	FillFloat
   282  	FillStr
   283  	FillLinear
   284  	FillPrevious
   285  )
   286  
   287  type Fill struct {
   288  	FillType int     `json:"-"`
   289  	Str      string  `json:"-"`
   290  	Float    float64 `json:"-"`
   291  	Int      int64   `json:"-"`
   292  	Boolean  bool    `json:"-"`
   293  }
   294  
   295  func (n *Fill) MarshalJSON() ([]byte, error) {
   296  	const output1 = `{"type":"%s"}`
   297  	const output2 = `{"type":"%s", "%s":%v}`
   298  
   299  	switch n.FillType {
   300  	case FillNil:
   301  		return []byte(fmt.Sprintf(output1, Nil)), nil
   302  
   303  	case FillInt:
   304  		return []byte(fmt.Sprintf(output2, "integer", "integer_val", n.Int)), nil
   305  
   306  	case FillFloat:
   307  		return []byte(fmt.Sprintf(output2, "float", "float_val", n.Float)), nil
   308  
   309  	case FillStr:
   310  		return []byte(fmt.Sprintf(output2, "str", "str_val", fmt.Sprintf(`"%s"`, n.Str))), nil
   311  
   312  	case FillLinear:
   313  		return []byte(fmt.Sprintf(output1, "linear")), nil
   314  
   315  	case FillPrevious:
   316  		return []byte(fmt.Sprintf(output1, "previous")), nil
   317  	}
   318  
   319  	return []byte(`""`), nil
   320  }
   321  
   322  func (n *Fill) String() string {
   323  	switch n.FillType {
   324  	case FillNil:
   325  		return "<nil>"
   326  	case FillInt:
   327  		return fmt.Sprintf("<%d>", n.Int)
   328  	case FillFloat:
   329  		return fmt.Sprintf("<%f>", n.Float)
   330  	case FillStr:
   331  		return fmt.Sprintf("<%s>", n.Str)
   332  	case FillLinear:
   333  		return "<linear>"
   334  	case FillPrevious:
   335  		return "<previous>"
   336  	}
   337  
   338  	log.Warn("invalid ifill: %+#v", n)
   339  	return ""
   340  }
   341  
   342  func (n *Fill) StringInfluxql() string {
   343  	switch n.FillType {
   344  	case FillNil:
   345  		return Nil
   346  	case FillInt:
   347  		return fmt.Sprintf("%d", n.Int)
   348  	case FillFloat:
   349  		return fmt.Sprintf("%f", n.Float)
   350  	case FillStr:
   351  		return n.Str
   352  	case FillLinear:
   353  		return "linear"
   354  	case FillPrevious:
   355  		return "previous"
   356  	}
   357  
   358  	log.Warn("invalid fill: %+#v", n)
   359  	return ""
   360  }
   361  
   362  func (n *Fill) Pos() *PositionRange { return nil } // TODO
   363  
   364  type FuncExpr struct {
   365  	Name  string `json:"name,omitempty"`
   366  	Param []Node `json:"param,omitempty"`
   367  	// Pos   *PositionRange
   368  }
   369  
   370  const (
   371  	fillFuncArgs = 2
   372  )
   373  
   374  func (n *FuncExpr) SplitFill() (val Node, fill *Fill, err error) {
   375  	switch strings.ToLower(n.Name) {
   376  	case "fill":
   377  		const typ = "(Nil,NumberLiteral,StringLiteral,PREVIOUS,LINEAR)"
   378  
   379  		if len(n.Param) != fillFuncArgs {
   380  			err = fmt.Errorf("fill function only accept 2 parameter, left value and %s", typ)
   381  			return
   382  		}
   383  
   384  		paramErr := fmt.Errorf("unknown fill function parameter, only accept %s", typ)
   385  
   386  		switch v := n.Param[1].(type) {
   387  		case *Identifier:
   388  			switch strings.ToLower(v.Name) {
   389  			case "previous":
   390  				fill = &Fill{FillType: FillPrevious}
   391  			case "linear":
   392  				fill = &Fill{FillType: FillLinear}
   393  			default:
   394  				err = paramErr
   395  				return
   396  			}
   397  
   398  		case *NilLiteral:
   399  			fill = &Fill{FillType: FillNil}
   400  
   401  		case *NumberLiteral:
   402  			if v.IsInt {
   403  				fill = &Fill{FillType: FillInt, Int: v.Int}
   404  			} else {
   405  				fill = &Fill{FillType: FillFloat, Float: v.Float}
   406  			}
   407  
   408  		case *StringLiteral:
   409  			fill = &Fill{FillType: FillStr, Str: v.Val}
   410  
   411  		default:
   412  			err = paramErr
   413  			return
   414  		}
   415  
   416  		val = n.Param[0]
   417  
   418  	default:
   419  		val = n
   420  	}
   421  
   422  	return //nolint:nakedret
   423  }
   424  
   425  func (n *FuncExpr) String() string {
   426  	arr := []string{}
   427  	for _, n := range n.Param {
   428  		arr = append(arr, n.String())
   429  	}
   430  	return fmt.Sprintf("%s(%s)", strings.ToLower(n.Name), strings.Join(arr, ", "))
   431  }
   432  
   433  func (n *FuncExpr) Pos() *PositionRange { return nil } // TODO
   434  
   435  type ESTRes struct {
   436  	Alias           map[string]string // 别名信息
   437  	SortFields      []string          // 返回字段有序列表
   438  	ClassNames      string            // metric 类型名称
   439  	Show            bool              // 是否是show查询
   440  	ShowFields      bool              // 是否是show fields查询
   441  	TimeField       string            // time字段
   442  	FLFuncCount     int               // first,last函数个数
   443  	AggsFromSize    int               // 聚合的分页
   444  	StartTime       int64             // 开始时间
   445  	EndTime         int64             // 结束时间
   446  	HighlightFields []string          // 高亮字段
   447  }
   448  
   449  // Helper tranlate中间结果.
   450  type Helper struct {
   451  	ESTResPtr *ESTRes // es translate,当结果转为influxdb结构使用
   452  }
   453  
   454  type DFQuery struct { // impl Node
   455  
   456  	// data source
   457  	Names          []string  `json:"names,omitempty"`
   458  	RegexNames     []*Regex  `json:"regex_names,omitempty"`
   459  	Targets        []*Target `json:"targets,omitempty"`
   460  	WhereCondition []Node    `json:"where_condition,omitempty"`
   461  
   462  	Namespace string `json:"namespace,omitempty"`
   463  
   464  	Subquery *DFQuery `json:"subquery,omitempty"`
   465  
   466  	GroupBy     *GroupBy     `json:"groupby,omitempty"`
   467  	OrderBy     *OrderBy     `json:"orderby,omitempty"`
   468  	Limit       *Limit       `json:"limit,omitempty"`
   469  	Offset      *Offset      `json:"offset,omitempty"`
   470  	SLimit      *SLimit      `json:"slimit,omitempty"`
   471  	SOffset     *SOffset     `json:"soffset,omitempty"`
   472  	TimeZone    *TimeZone    `json:"timezone,omitempty"`
   473  	SearchAfter *SearchAfter `json:"search_after,omitempty"` // search_after
   474  	Helper      *Helper      `json:"-"`
   475  
   476  	Anonymous bool `json:"-"`
   477  	Highlight bool `json:"highlight,omitempty"`
   478  }
   479  
   480  func (m *DFQuery) JSON() ([]byte, error) {
   481  	// json.Marshal escaping < and >
   482  	// https://stackoverflow.com/questions/28595664/how-to-stop-json-marshal-from-escaping-and
   483  	buffer := &bytes.Buffer{}
   484  	encoder := json.NewEncoder(buffer)
   485  	encoder.SetEscapeHTML(false)
   486  	err := encoder.Encode(m)
   487  
   488  	// Encode() followed by a newline character
   489  	return buffer.Bytes(), err
   490  }
   491  
   492  // IsAllTargets 未指定 target 或为手动填写 "*",即 ALL,like SELECT * FROM XX.
   493  func (m *DFQuery) IsAllTargets() bool {
   494  	return m.IsMatchTargetsNum(0)
   495  }
   496  
   497  func (m *DFQuery) IsMatchTargetsNum(num int) bool {
   498  	if len(m.Targets) == 0 || m.Targets[0].Col.String() == "*" {
   499  		return num == 0
   500  	}
   501  	return len(m.Targets) == num
   502  }
   503  
   504  func (m *DFQuery) GroupByList() []string {
   505  	if m.GroupBy == nil {
   506  		return nil
   507  	}
   508  	return m.GroupBy.ColumnList()
   509  }
   510  
   511  func (m *DFQuery) String() string {
   512  	parts := []string{m.From()}
   513  
   514  	if m.Targets != nil {
   515  		arr := []string{}
   516  		for _, t := range m.Targets {
   517  			arr = append(arr, t.String())
   518  		}
   519  
   520  		parts = append(parts, ":("+strings.Join(arr, ", ")+")")
   521  	}
   522  
   523  	if m.WhereCondition != nil {
   524  		arr := []string{}
   525  		for _, f := range m.WhereCondition {
   526  			arr = append(arr, f.String())
   527  		}
   528  		parts = append(parts, "{"+strings.Join(arr, ", ")+"}")
   529  	}
   530  
   531  	if m.GroupBy != nil {
   532  		parts = append(parts, " "+m.GroupBy.String())
   533  	}
   534  
   535  	if m.OrderBy != nil {
   536  		parts = append(parts, " "+m.OrderBy.String())
   537  	}
   538  
   539  	if m.Limit != nil {
   540  		parts = append(parts, " "+m.Limit.String())
   541  	}
   542  
   543  	if m.Offset != nil {
   544  		parts = append(parts, " "+m.Offset.String())
   545  	}
   546  
   547  	if m.SLimit != nil {
   548  		parts = append(parts, " "+m.SLimit.String())
   549  	}
   550  
   551  	if m.SOffset != nil {
   552  		parts = append(parts, " "+m.SOffset.String())
   553  	}
   554  
   555  	if m.TimeZone != nil {
   556  		parts = append(parts, " "+m.TimeZone.String())
   557  	}
   558  
   559  	return strings.Join(parts, "")
   560  }
   561  
   562  func (m *DFQuery) From() string {
   563  	arr := []string{}
   564  
   565  	arr = append(arr, m.Names...)
   566  
   567  	for _, x := range m.RegexNames {
   568  		arr = append(arr, x.String())
   569  	}
   570  
   571  	if m.Subquery != nil {
   572  		arr = append(arr, "("+m.Subquery.String()+")")
   573  	}
   574  
   575  	return m.Namespace + "::" + strings.Join(arr, ",")
   576  }
   577  
   578  func (m *DFQuery) Pos() *PositionRange { return nil } // TODO
   579  
   580  type Target struct { // impl Node
   581  	Col    Node   `json:"col,omitempty"`
   582  	Alias  string `json:"alias,omitempty"`
   583  	Fill   *Fill  `json:"fill,omitempty"`
   584  	Talias string `json:"tailas,omitempty"` // dql翻译别名
   585  }
   586  
   587  func (n *Target) String() string {
   588  	if n.Col == nil {
   589  		panic("unreachable: Target col is nil")
   590  	}
   591  
   592  	if n.Fill != nil {
   593  		fillFn := &FuncExpr{
   594  			Name:  "fill", // TODO: support upper and lower
   595  			Param: []Node{n.Col, n.Fill},
   596  		}
   597  		return fillFn.String()
   598  	}
   599  
   600  	var res []string
   601  
   602  	if c := n.Col.String(); c != "" {
   603  		res = append(res, c)
   604  	}
   605  
   606  	if n.Alias != "" {
   607  		res = append(res, fmt.Sprintf("AS %s", n.Alias))
   608  	}
   609  
   610  	if n.Fill != nil && n.Fill.String() != "" {
   611  		res = append(res, n.Fill.String())
   612  	}
   613  
   614  	return strings.Join(res, " ")
   615  }
   616  
   617  func (n *Target) String2() string {
   618  	if n.Alias != "" {
   619  		return n.Alias
   620  	}
   621  	return n.String()
   622  }
   623  
   624  func (n *Target) Pos() *PositionRange { return nil /* TODO */ }
   625  
   626  type TimeResolution struct {
   627  	Duration time.Duration
   628  	Auto     bool
   629  	PointNum *NumberLiteral
   630  }
   631  
   632  func (n *TimeResolution) String() string {
   633  	if n.Auto {
   634  		return "auto"
   635  	}
   636  	if n.PointNum != nil {
   637  		return fmt.Sprintf("auto(%s)", n.PointNum)
   638  	}
   639  	return fmt.Sprintf("%v", n.Duration)
   640  }
   641  
   642  func (n *TimeResolution) Pos() *PositionRange { return nil /* TODO */ }
   643  
   644  type Expr interface {
   645  	Node
   646  	Type() ValueType
   647  	DQLExpr()
   648  }
   649  
   650  type Regex struct {
   651  	Regex string `json:"regex,omitempty"`
   652  	Re    *regexp.Regexp
   653  }
   654  
   655  func (e *Regex) MarshalJSON() ([]byte, error) {
   656  	return []byte(fmt.Sprintf(`"%s"`, e.String())), nil
   657  }
   658  
   659  func (e *Regex) Type() ValueType     { return "" /* TODO */ }
   660  func (e *Regex) String() string      { return fmt.Sprintf("re('%s')", e.Regex) }
   661  func (e *Regex) Pos() *PositionRange { return nil } // TODO
   662  func (e *Regex) DQLExpr()            {}             // not used
   663  
   664  type StringLiteral struct {
   665  	Val string `json:"val,omitempty"`
   666  }
   667  
   668  func (e *StringLiteral) Type() ValueType     { return "" /* TODO */ }
   669  func (e *StringLiteral) DQLExpr()            { /* not used */ }
   670  func (e *StringLiteral) String() string      { return fmt.Sprintf("'%s'", e.Val) }
   671  func (e *StringLiteral) Pos() *PositionRange { return nil /* TODO */ }
   672  
   673  type BinaryExpr struct { // impl Expr & Node
   674  	Op         ItemType `json:"operator,omitempty"`
   675  	LHS        Node     `json:"left,omitempty"`
   676  	RHS        Node     `json:"right,omitempty"`
   677  	ReturnBool bool     `json:"-"`
   678  }
   679  
   680  func (e *BinaryExpr) Type() ValueType     { return "" }  // TODO
   681  func (e *BinaryExpr) Pos() *PositionRange { return nil } // TODO
   682  func (e *BinaryExpr) String() string {
   683  	switch e.Op {
   684  	case MATCH, NOT_MATCH:
   685  		var originNodeList NodeList
   686  		for _, elem := range e.RHS.(NodeList) {
   687  			switch x := elem.(type) {
   688  			case *Regex:
   689  				originNodeList = append(originNodeList, &StringLiteral{Val: x.Regex})
   690  			default:
   691  				log.Errorf("RHS expect *Regex, got %s(%s)", reflect.TypeOf(elem), elem.String())
   692  			}
   693  		}
   694  		return fmt.Sprintf("%s %s %s", e.LHS.String(), e.Op.String(), originNodeList.String())
   695  	default:
   696  		return fmt.Sprintf("%s %s %s",
   697  			e.LHS.String(),
   698  			e.Op.String(),
   699  			e.RHS.String())
   700  	}
   701  }
   702  
   703  func (e *BinaryExpr) DQLExpr() {} // not used
   704  
   705  type ParenExpr struct {
   706  	Param Node `json:"paren"`
   707  }
   708  
   709  func (*ParenExpr) Type() ValueType     { return "" }  // TODO
   710  func (*ParenExpr) Pos() *PositionRange { return nil } // TODO
   711  func (p *ParenExpr) String() string {
   712  	return fmt.Sprintf("(%s)", p.Param.String())
   713  }
   714  
   715  func (*ParenExpr) DQLExpr() {} // not used
   716  
   717  type NumberLiteral struct {
   718  	IsInt bool
   719  	Float float64
   720  	Int   int64
   721  }
   722  
   723  func (e *NumberLiteral) IsPositiveInteger() bool {
   724  	return e.IsInt && e.Int > 0
   725  }
   726  
   727  func (e *NumberLiteral) MarshalJSON() ([]byte, error) {
   728  	return []byte(e.String()), nil
   729  }
   730  
   731  func (e *NumberLiteral) Type() ValueType     { return "" }
   732  func (e *NumberLiteral) DQLExpr()            {}
   733  func (e *NumberLiteral) Pos() *PositionRange { return nil } // not used
   734  func (e *NumberLiteral) Reverse() {
   735  	if e.IsInt {
   736  		e.Int = -e.Int
   737  	} else {
   738  		e.Float = -e.Float
   739  	}
   740  }
   741  
   742  func (e *NumberLiteral) String() string {
   743  	if e.IsInt {
   744  		return fmt.Sprintf("%d", e.Int)
   745  	} else {
   746  		return fmt.Sprintf("%f", e.Float)
   747  	}
   748  }
   749  
   750  type Identifier struct { // impl Expr
   751  	Name string `json:"val,omitempty"`
   752  }
   753  
   754  func (e *Identifier) String() string      { return e.Name }
   755  func (e *Identifier) Pos() *PositionRange { return nil } // TODO
   756  func (e *Identifier) DQLExpr()            {}             // not used
   757  func (e *Identifier) Type() ValueType     { return "" }
   758  
   759  type StaticCast struct {
   760  	IsInt   bool
   761  	IsFloat bool
   762  	Val     *Identifier
   763  }
   764  
   765  func (e *StaticCast) MarshalJSON() ([]byte, error) {
   766  	const res = `{"%s":"%s"}`
   767  	if e.IsInt {
   768  		return []byte(fmt.Sprintf(res, "int", e.Val.String())), nil
   769  	}
   770  	if e.IsFloat {
   771  		return []byte(fmt.Sprintf(res, "float", e.Val.String())), nil
   772  	}
   773  	return nil, fmt.Errorf("unreachable")
   774  }
   775  
   776  func (e *StaticCast) String() string {
   777  	if e.IsInt {
   778  		return fmt.Sprintf("int(%s)", e.Val.Name)
   779  	}
   780  	if e.IsFloat {
   781  		return fmt.Sprintf("float(%s)", e.Val.Name)
   782  	}
   783  	return ""
   784  }
   785  func (e *StaticCast) Pos() *PositionRange { return nil } // TODO
   786  func (e *StaticCast) DQLExpr()            {}             // not used
   787  func (e *StaticCast) Type() ValueType     { return "" }
   788  
   789  //
   790  // various stmt definition.
   791  //
   792  
   793  type Statement interface {
   794  	Node
   795  	DQLStmt() // not used
   796  }
   797  
   798  // OuterFunc outerFunc.
   799  type OuterFunc struct {
   800  	Func         *FuncExpr     `json:"func,omitempty"`
   801  	FuncArgVals  []interface{} `json:"func_arg_vals,omitempty"`
   802  	FuncArgTypes []string      `json:"func_arg_types,omitempty"`
   803  	FuncArgNames []string      `json:"func_arg_names,omitempty"`
   804  }
   805  
   806  type OuterFuncs struct {
   807  	Funcs []*OuterFunc `json:"funcs,omitempty"`
   808  }
   809  
   810  func (ofuncs *OuterFuncs) JSON() ([]byte, error) {
   811  	// json.Marshal escaping < and >
   812  	// https://stackoverflow.com/questions/28595664/how-to-stop-json-marshal-from-escaping-and
   813  	buffer := &bytes.Buffer{}
   814  	encoder := json.NewEncoder(buffer)
   815  	encoder.SetEscapeHTML(false)
   816  	err := encoder.Encode(ofuncs)
   817  
   818  	// Encode() followed by a newline character
   819  	return buffer.Bytes(), err
   820  }
   821  
   822  func (ofuncs *OuterFunc) String() string {
   823  	return "outer func"
   824  }
   825  
   826  func (ofuncs *OuterFunc) Pos() *PositionRange {
   827  	return nil
   828  }
   829  
   830  func (ofuncs *OuterFuncs) String() string {
   831  	// TODO
   832  	return "outer func"
   833  }
   834  
   835  func (ofuncs *OuterFuncs) Pos() *PositionRange {
   836  	return nil
   837  }
   838  
   839  // DeleteFunc delete info.
   840  type DeleteFunc struct {
   841  	// (1) dql语句;
   842  	// (2) es indexName, 索引名称不包含wsid,例如: rum, log等;
   843  	// (3) influxdb measurement name, 例如: cpu,mem等
   844  	StrDql            string
   845  	Func              *FuncExpr
   846  	DeleteIndex       bool // 是否删除整个ES索引
   847  	DeleteMeasurement bool // 是否删除整个Influxdb measurement
   848  }
   849  
   850  func (d *DeleteFunc) String() string {
   851  	return "outer delete func"
   852  }
   853  
   854  func (d *DeleteFunc) Pos() *PositionRange {
   855  	return nil
   856  }
   857  
   858  type Evaluable interface {
   859  	Eval(data KVs) bool
   860  }
   861  
   862  type WhereCondition struct {
   863  	conditions []Node
   864  }
   865  
   866  func (x *WhereCondition) Eval(data KVs) bool {
   867  	for _, c := range x.conditions {
   868  		switch expr := c.(type) {
   869  		case *BinaryExpr:
   870  			if !expr.Eval(data) {
   871  				return false
   872  			}
   873  
   874  		default:
   875  			log.Errorf("Eval only accept BinaryExpr")
   876  			return false
   877  		}
   878  	}
   879  
   880  	return true
   881  }
   882  
   883  func (x *WhereCondition) String() string {
   884  	arr := []string{}
   885  	for _, f := range x.conditions {
   886  		arr = append(arr, f.String())
   887  	}
   888  
   889  	return "{" + strings.Join(arr, " and ") + "}"
   890  }
   891  
   892  func (x *WhereCondition) Pos() *PositionRange {
   893  	return nil
   894  }
   895  
   896  type WhereConditions []Node
   897  
   898  func (x WhereConditions) Pos() *PositionRange { return nil }
   899  
   900  func (x WhereConditions) String() string {
   901  	arr := []string{}
   902  	for _, c := range x {
   903  		if c == nil {
   904  			continue
   905  		}
   906  
   907  		arr = append(arr, c.String())
   908  	}
   909  	return strings.Join(arr, "; ")
   910  }
   911  
   912  func (x WhereConditions) Eval(data KVs) int {
   913  	for idx, item := range x {
   914  		switch c := item.(type) {
   915  		case *WhereCondition:
   916  			if c.Eval(data) {
   917  				return idx
   918  			}
   919  
   920  		default:
   921  			log.Warnf("invalid where condition: %s", c)
   922  			return -1
   923  		}
   924  	}
   925  
   926  	return -1
   927  }