github.com/pingcap/tidb/parser@v0.0.0-20231013125129-93a834a6bf8d/opcode/opcode.go (about)

     1  // Copyright 2015 PingCAP, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package opcode
    15  
    16  import (
    17  	"io"
    18  
    19  	"github.com/pingcap/tidb/parser/format"
    20  )
    21  
    22  // Op is opcode type.
    23  type Op int
    24  
    25  // List operators.
    26  const (
    27  	LogicAnd Op = iota + 1
    28  	LeftShift
    29  	RightShift
    30  	LogicOr
    31  	GE
    32  	LE
    33  	EQ
    34  	NE
    35  	LT
    36  	GT
    37  	Plus
    38  	Minus
    39  	And
    40  	Or
    41  	Mod
    42  	Xor
    43  	Div
    44  	Mul
    45  	Not
    46  	Not2
    47  	BitNeg
    48  	IntDiv
    49  	LogicXor
    50  	NullEQ
    51  	In
    52  	Like
    53  	Case
    54  	Regexp
    55  	IsNull
    56  	IsTruth
    57  	IsFalsity
    58  )
    59  
    60  var ops = [...]struct {
    61  	name      string
    62  	literal   string
    63  	isKeyword bool
    64  }{
    65  	LogicAnd: {
    66  		name:      "and",
    67  		literal:   "AND",
    68  		isKeyword: true,
    69  	},
    70  	LogicOr: {
    71  		name:      "or",
    72  		literal:   "OR",
    73  		isKeyword: true,
    74  	},
    75  	LogicXor: {
    76  		name:      "xor",
    77  		literal:   "XOR",
    78  		isKeyword: true,
    79  	},
    80  	LeftShift: {
    81  		name:      "leftshift",
    82  		literal:   "<<",
    83  		isKeyword: false,
    84  	},
    85  	RightShift: {
    86  		name:      "rightshift",
    87  		literal:   ">>",
    88  		isKeyword: false,
    89  	},
    90  	GE: {
    91  		name:      "ge",
    92  		literal:   ">=",
    93  		isKeyword: false,
    94  	},
    95  	LE: {
    96  		name:      "le",
    97  		literal:   "<=",
    98  		isKeyword: false,
    99  	},
   100  	EQ: {
   101  		name:      "eq",
   102  		literal:   "=",
   103  		isKeyword: false,
   104  	},
   105  	NE: {
   106  		name:      "ne",
   107  		literal:   "!=", // perhaps should use `<>` here
   108  		isKeyword: false,
   109  	},
   110  	LT: {
   111  		name:      "lt",
   112  		literal:   "<",
   113  		isKeyword: false,
   114  	},
   115  	GT: {
   116  		name:      "gt",
   117  		literal:   ">",
   118  		isKeyword: false,
   119  	},
   120  	Plus: {
   121  		name:      "plus",
   122  		literal:   "+",
   123  		isKeyword: false,
   124  	},
   125  	Minus: {
   126  		name:      "minus",
   127  		literal:   "-",
   128  		isKeyword: false,
   129  	},
   130  	And: {
   131  		name:      "bitand",
   132  		literal:   "&",
   133  		isKeyword: false,
   134  	},
   135  	Or: {
   136  		name:      "bitor",
   137  		literal:   "|",
   138  		isKeyword: false,
   139  	},
   140  	Mod: {
   141  		name:      "mod",
   142  		literal:   "%",
   143  		isKeyword: false,
   144  	},
   145  	Xor: {
   146  		name:      "bitxor",
   147  		literal:   "^",
   148  		isKeyword: false,
   149  	},
   150  	Div: {
   151  		name:      "div",
   152  		literal:   "/",
   153  		isKeyword: false,
   154  	},
   155  	Mul: {
   156  		name:      "mul",
   157  		literal:   "*",
   158  		isKeyword: false,
   159  	},
   160  	Not: {
   161  		name:      "not",
   162  		literal:   "not ",
   163  		isKeyword: true,
   164  	},
   165  	Not2: {
   166  		name:      "!",
   167  		literal:   "!",
   168  		isKeyword: false,
   169  	},
   170  	BitNeg: {
   171  		name:      "bitneg",
   172  		literal:   "~",
   173  		isKeyword: false,
   174  	},
   175  	IntDiv: {
   176  		name:      "intdiv",
   177  		literal:   "DIV",
   178  		isKeyword: true,
   179  	},
   180  	NullEQ: {
   181  		name:      "nulleq",
   182  		literal:   "<=>",
   183  		isKeyword: false,
   184  	},
   185  	In: {
   186  		name:      "in",
   187  		literal:   "IN",
   188  		isKeyword: true,
   189  	},
   190  	Like: {
   191  		name:      "like",
   192  		literal:   "LIKE",
   193  		isKeyword: true,
   194  	},
   195  	Case: {
   196  		name:      "case",
   197  		literal:   "CASE",
   198  		isKeyword: true,
   199  	},
   200  	Regexp: {
   201  		name:      "regexp",
   202  		literal:   "REGEXP",
   203  		isKeyword: true,
   204  	},
   205  	IsNull: {
   206  		name:      "isnull",
   207  		literal:   "IS NULL",
   208  		isKeyword: true,
   209  	},
   210  	IsTruth: {
   211  		name:      "istrue",
   212  		literal:   "IS TRUE",
   213  		isKeyword: true,
   214  	},
   215  	IsFalsity: {
   216  		name:      "isfalse",
   217  		literal:   "IS FALSE",
   218  		isKeyword: true,
   219  	},
   220  }
   221  
   222  // String implements Stringer interface.
   223  func (o Op) String() string {
   224  	return ops[o].name
   225  }
   226  
   227  // Format the ExprNode into a Writer.
   228  func (o Op) Format(w io.Writer) {
   229  	io.WriteString(w, ops[o].literal)
   230  }
   231  
   232  // IsKeyword returns whether the operator is a keyword.
   233  func (o Op) IsKeyword() bool {
   234  	return ops[o].isKeyword
   235  }
   236  
   237  // Restore the Op into a Writer
   238  func (o Op) Restore(ctx *format.RestoreCtx) error {
   239  	info := &ops[o]
   240  	if info.isKeyword {
   241  		ctx.WriteKeyWord(info.literal)
   242  	} else {
   243  		ctx.WritePlain(info.literal)
   244  	}
   245  	return nil
   246  }