opcode.go 3.7 KB

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