github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/expr/token.go (about)

     1  // Modifications Copyright (c) 2017-2018 Uber Technologies, Inc.
     2  // Copyright (c) 2013-2016 Errplane Inc.
     3  //
     4  // Permission is hereby granted, free of charge, to any person obtaining a copy of
     5  // this software and associated documentation files (the "Software"), to deal in
     6  // the Software without restriction, including without limitation the rights to
     7  // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
     8  // the Software, and to permit persons to whom the Software is furnished to do so,
     9  // subject to the following conditions:
    10  //
    11  // The above copyright notice and this permission notice shall be included in all
    12  // copies or substantial portions of the Software.
    13  //
    14  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    16  // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    17  // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    18  // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    19  // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    20  
    21  package expr
    22  
    23  import (
    24  	"bytes"
    25  	"strings"
    26  )
    27  
    28  // Token is a lexical token of the InfluxQL language.
    29  type Token int
    30  
    31  const (
    32  	// Special tokens
    33  	ILLEGAL Token = iota
    34  	EOF
    35  	WS
    36  
    37  	literal_beg
    38  	// Literals
    39  	IDENT     // main
    40  	NUMBER    // 12345.67
    41  	STRING    // "abc"
    42  	BADSTRING // "abc
    43  	BADESCAPE // \q
    44  	NULL      // NULL
    45  	UNKNOWN   // UNKNOWN
    46  	TRUE      // true
    47  	FALSE     // false
    48  	literal_end
    49  
    50  	operator_beg
    51  	// Operators
    52  	unary_operator_beg
    53  	EXCLAMATION // !
    54  	UNARY_MINUS // -
    55  	NOT         // NOT
    56  	BITWISE_NOT // ~0
    57  
    58  	// Date operators
    59  	GET_WEEK_START
    60  	GET_MONTH_START
    61  	GET_QUARTER_START
    62  	GET_YEAR_START
    63  	GET_DAY_OF_MONTH
    64  	GET_DAY_OF_YEAR
    65  	GET_MONTH_OF_YEAR
    66  	GET_QUARTER_OF_YEAR
    67  	// hll operator
    68  	GET_HLL_VALUE
    69  	unary_operator_end
    70  
    71  	derived_unary_operator_beg
    72  	IS_NULL     // IS NULL
    73  	IS_NOT_NULL // IS NOT NULL
    74  	IS_TRUE     // IS TRUE
    75  	IS_FALSE    // IS FALSE
    76  	derived_unary_operator_end
    77  
    78  	binary_operator_beg
    79  	ADD        // +
    80  	SUB        // -
    81  	MUL        // *
    82  	DIV        // /
    83  	MOD        // %
    84  	FLOOR      // floor
    85  	CONVERT_TZ // convert_tz
    86  
    87  	BITWISE_AND         // &
    88  	BITWISE_OR          // |
    89  	BITWISE_XOR         // ^
    90  	BITWISE_LEFT_SHIFT  // <<
    91  	BITWISE_RIGHT_SHIFT // >>
    92  
    93  	AND // AND
    94  	OR  // OR
    95  
    96  	IN     // IN
    97  	NOT_IN // NOT_IN
    98  	IS     // IS
    99  	NEQ    // !=
   100  	// Do not modify the order of the following 5 operators
   101  	EQ  // =
   102  	LT  // <
   103  	LTE // <=
   104  	GT  // >
   105  	GTE // >=
   106  
   107  	// Geo intersects
   108  	GEOGRAPHY_INTERSECTS
   109  	binary_operator_end
   110  	operator_end
   111  
   112  	LPAREN // (
   113  	RPAREN // )
   114  	COMMA  // ,
   115  	DOT    // .
   116  
   117  	keyword_beg
   118  	// Keywords
   119  	ALL
   120  	AS
   121  	ASC
   122  	BEGIN
   123  	BY
   124  	CASE
   125  	DEFAULT
   126  	DELETE
   127  	DESC
   128  	DISTINCT
   129  	DROP
   130  	ELSE
   131  	END
   132  	EXISTS
   133  	FIELD
   134  	FOR
   135  	FROM
   136  	GROUP
   137  	IF
   138  	INF
   139  	INNER
   140  	INSERT
   141  	KEY
   142  	KEYS
   143  	LIMIT
   144  	OFFSET
   145  	ON
   146  	ORDER
   147  	SELECT
   148  	THEN
   149  	TO
   150  	VALUES
   151  	WHEN
   152  	WHERE
   153  	WITH
   154  	keyword_end
   155  )
   156  
   157  var tokens = map[Token]string{
   158  	ILLEGAL: "ILLEGAL",
   159  	EOF:     "EOF",
   160  	WS:      "WS",
   161  
   162  	IDENT:     "IDENT",
   163  	NUMBER:    "NUMBER",
   164  	STRING:    "STRING",
   165  	BADSTRING: "BADSTRING",
   166  	BADESCAPE: "BADESCAPE",
   167  	NULL:      "NULL",
   168  	UNKNOWN:   "UNKNOWN",
   169  	TRUE:      "TRUE",
   170  	FALSE:     "FALSE",
   171  
   172  	EXCLAMATION: "!",
   173  	UNARY_MINUS: "-",
   174  	NOT:         "NOT",
   175  	IS_NULL:     "IS NULL",
   176  	IS_NOT_NULL: "IS NOT NULL",
   177  	IS_TRUE:     "IS TRUE",
   178  	IS_FALSE:    "IS FALSE",
   179  
   180  	GET_WEEK_START:      "GET_WEEK_START",
   181  	GET_MONTH_START:     "GET_MONTH_START",
   182  	GET_QUARTER_START:   "GET_QUARTER_START",
   183  	GET_YEAR_START:      "GET_YEAR_START",
   184  	GET_DAY_OF_MONTH:    "GET_DAY_OF_MONTH",
   185  	GET_DAY_OF_YEAR:     "GET_DAY_OF_YEAR",
   186  	GET_MONTH_OF_YEAR:   "GET_MONTH_OF_YEAR",
   187  	GET_QUARTER_OF_YEAR: "GET_QUARTER_OF_YEAR",
   188  	GET_HLL_VALUE:       "GET_HLL_VALUE",
   189  
   190  	ADD:        "+",
   191  	SUB:        "-",
   192  	MUL:        "*",
   193  	DIV:        "/",
   194  	MOD:        "%",
   195  	FLOOR:      "FLOOR",
   196  	CONVERT_TZ: "CONVERT_TZ",
   197  
   198  	BITWISE_AND:         "&",
   199  	BITWISE_OR:          "|",
   200  	BITWISE_NOT:         "~",
   201  	BITWISE_XOR:         "^",
   202  	BITWISE_LEFT_SHIFT:  "<<",
   203  	BITWISE_RIGHT_SHIFT: ">>",
   204  
   205  	AND: "AND",
   206  	OR:  "OR",
   207  
   208  	IN:     "IN",
   209  	NOT_IN: "NOT IN",
   210  	IS:     "IS",
   211  	EQ:     "=",
   212  	NEQ:    "!=",
   213  	LT:     "<",
   214  	LTE:    "<=",
   215  	GT:     ">",
   216  	GTE:    ">=",
   217  
   218  	GEOGRAPHY_INTERSECTS: "GEOGRAPHY_INTERSECTS",
   219  
   220  	LPAREN: "(",
   221  	RPAREN: ")",
   222  	COMMA:  ",",
   223  	DOT:    ".",
   224  
   225  	ALL:      "ALL",
   226  	AS:       "AS",
   227  	ASC:      "ASC",
   228  	BEGIN:    "BEGIN",
   229  	BY:       "BY",
   230  	CASE:     "CASE",
   231  	DEFAULT:  "DEFAULT",
   232  	DELETE:   "DELETE",
   233  	DESC:     "DESC",
   234  	DROP:     "DROP",
   235  	DISTINCT: "DISTINCT",
   236  	ELSE:     "ELSE",
   237  	END:      "END",
   238  	EXISTS:   "EXISTS",
   239  	FIELD:    "FIELD",
   240  	FOR:      "FOR",
   241  	FROM:     "FROM",
   242  	GROUP:    "GROUP",
   243  	IF:       "IF",
   244  	INF:      "INF",
   245  	INNER:    "INNER",
   246  	INSERT:   "INSERT",
   247  	KEY:      "KEY",
   248  	KEYS:     "KEYS",
   249  	LIMIT:    "LIMIT",
   250  	OFFSET:   "OFFSET",
   251  	ON:       "ON",
   252  	ORDER:    "ORDER",
   253  	SELECT:   "SELECT",
   254  	THEN:     "THEN",
   255  	TO:       "TO",
   256  	VALUES:   "VALUES",
   257  	WHEN:     "WHEN",
   258  	WHERE:    "WHERE",
   259  	WITH:     "WITH",
   260  }
   261  
   262  var keywords map[string]Token
   263  
   264  func init() {
   265  	keywords = make(map[string]Token)
   266  	for tok := keyword_beg + 1; tok < keyword_end; tok++ {
   267  		keywords[strings.ToLower(tokens[tok])] = tok
   268  	}
   269  	for _, tok := range []Token{AND, OR, IN, IS, NOT} {
   270  		keywords[strings.ToLower(tokens[tok])] = tok
   271  	}
   272  	keywords["null"] = NULL
   273  	keywords["unknown"] = UNKNOWN
   274  	keywords["true"] = TRUE
   275  	keywords["false"] = FALSE
   276  }
   277  
   278  // String returns the string representation of the token.
   279  func (tok Token) String() string {
   280  	if tok >= 0 && tok < Token(len(tokens)) {
   281  		return tokens[tok]
   282  	}
   283  	return ""
   284  }
   285  
   286  func (tok Token) MarshalJSON() ([]byte, error) {
   287  	buffer := bytes.NewBufferString(`"`)
   288  	buffer.WriteString(tokens[tok])
   289  	buffer.WriteString(`"`)
   290  	return buffer.Bytes(), nil
   291  }
   292  
   293  // Precedence returns the operator precedence of the binary operator token.
   294  func (tok Token) Precedence() int {
   295  	switch tok {
   296  	case OR:
   297  		return 1
   298  	case AND:
   299  		return 2
   300  	case NOT:
   301  		return 3
   302  	case IN, NOT_IN, IS, EQ, NEQ, LT, LTE, GT, GTE:
   303  		return 4
   304  	case BITWISE_OR:
   305  		return 5
   306  	case BITWISE_AND:
   307  		return 6
   308  	case BITWISE_LEFT_SHIFT, BITWISE_RIGHT_SHIFT:
   309  		return 7
   310  	case ADD, SUB:
   311  		return 8
   312  	case MUL, DIV, MOD:
   313  		return 9
   314  	case BITWISE_XOR:
   315  		return 10
   316  	case UNARY_MINUS, BITWISE_NOT, FLOOR, CONVERT_TZ:
   317  		return 11
   318  	case EXCLAMATION:
   319  		return 12
   320  	}
   321  	return 0
   322  }
   323  
   324  func (tok Token) isUnaryOperator() bool {
   325  	return tok > unary_operator_beg && tok < unary_operator_end
   326  }
   327  
   328  func (tok Token) isDerivedUnaryOperator() bool {
   329  	return tok > derived_unary_operator_beg && tok < derived_unary_operator_end
   330  }
   331  
   332  func (tok Token) isBinaryOperator() bool {
   333  	return tok > binary_operator_beg && tok < binary_operator_end
   334  }
   335  
   336  // tokstr returns a literal if provided, otherwise returns the token string.
   337  func tokstr(tok Token, lit string) string {
   338  	if lit != "" {
   339  		return lit
   340  	}
   341  	return tok.String()
   342  }
   343  
   344  // Lookup returns the token associated with a given string.
   345  func Lookup(ident string) Token {
   346  	if tok, ok := keywords[strings.ToLower(ident)]; ok {
   347  		return tok
   348  	}
   349  	return IDENT
   350  }
   351  
   352  // Pos specifies the line and character position of a token.
   353  // The Char and Line are both zero-based indexes.
   354  type Pos struct {
   355  	Line int
   356  	Char int
   357  }