/vendor/gopkg.in/src-d/go-mysql-server.v0/sql/expression/comparison.go

https://github.com/campoy/justforfunc · Go · 613 lines · 441 code · 122 blank · 50 comment · 140 complexity · 18113abf23384771fece4ca1048f5c30 MD5 · raw file

  1. package expression
  2. import (
  3. "fmt"
  4. errors "gopkg.in/src-d/go-errors.v1"
  5. "gopkg.in/src-d/go-mysql-server.v0/internal/regex"
  6. "gopkg.in/src-d/go-mysql-server.v0/sql"
  7. )
  8. // Comparer implements a comparison expression.
  9. type Comparer interface {
  10. sql.Expression
  11. Compare(ctx *sql.Context, row sql.Row) (int, error)
  12. Left() sql.Expression
  13. Right() sql.Expression
  14. }
  15. // ErrNilOperand ir returned if some or both of the comparison's operands is nil.
  16. var ErrNilOperand = errors.NewKind("nil operand found in comparison")
  17. type comparison struct {
  18. BinaryExpression
  19. compareType sql.Type
  20. }
  21. func newComparison(left, right sql.Expression) comparison {
  22. return comparison{BinaryExpression{left, right}, nil}
  23. }
  24. // Compare the two given values using the types of the expressions in the comparison.
  25. // Since both types should be equal, it does not matter which type is used, but for
  26. // reference, the left type is always used.
  27. func (c *comparison) Compare(ctx *sql.Context, row sql.Row) (int, error) {
  28. left, right, err := c.evalLeftAndRight(ctx, row)
  29. if err != nil {
  30. return 0, err
  31. }
  32. if left == nil || right == nil {
  33. return 0, ErrNilOperand.New()
  34. }
  35. if c.Left().Type() == c.Right().Type() {
  36. return c.Left().Type().Compare(left, right)
  37. }
  38. left, right, err = c.castLeftAndRight(left, right)
  39. if err != nil {
  40. return 0, err
  41. }
  42. return c.compareType.Compare(left, right)
  43. }
  44. func (c *comparison) evalLeftAndRight(ctx *sql.Context, row sql.Row) (interface{}, interface{}, error) {
  45. left, err := c.Left().Eval(ctx, row)
  46. if err != nil {
  47. return nil, nil, err
  48. }
  49. right, err := c.Right().Eval(ctx, row)
  50. if err != nil {
  51. return nil, nil, err
  52. }
  53. return left, right, nil
  54. }
  55. func (c *comparison) castLeftAndRight(left, right interface{}) (interface{}, interface{}, error) {
  56. if sql.IsNumber(c.Left().Type()) || sql.IsNumber(c.Right().Type()) {
  57. if sql.IsDecimal(c.Left().Type()) || sql.IsDecimal(c.Right().Type()) {
  58. left, right, err := convertLeftAndRight(left, right, ConvertToDecimal)
  59. if err != nil {
  60. return nil, nil, err
  61. }
  62. c.compareType = sql.Float64
  63. return left, right, nil
  64. }
  65. if sql.IsSigned(c.Left().Type()) || sql.IsSigned(c.Right().Type()) {
  66. left, right, err := convertLeftAndRight(left, right, ConvertToSigned)
  67. if err != nil {
  68. return nil, nil, err
  69. }
  70. c.compareType = sql.Int64
  71. return left, right, nil
  72. }
  73. left, right, err := convertLeftAndRight(left, right, ConvertToUnsigned)
  74. if err != nil {
  75. return nil, nil, err
  76. }
  77. c.compareType = sql.Uint64
  78. return left, right, nil
  79. }
  80. left, right, err := convertLeftAndRight(left, right, ConvertToChar)
  81. if err != nil {
  82. return nil, nil, err
  83. }
  84. c.compareType = sql.Text
  85. return left, right, nil
  86. }
  87. func convertLeftAndRight(left, right interface{}, convertTo string) (interface{}, interface{}, error) {
  88. l, err := convertValue(left, convertTo)
  89. if err != nil {
  90. return nil, nil, err
  91. }
  92. r, err := convertValue(right, convertTo)
  93. if err != nil {
  94. return nil, nil, err
  95. }
  96. return l, r, nil
  97. }
  98. // Type implements the Expression interface.
  99. func (*comparison) Type() sql.Type {
  100. return sql.Boolean
  101. }
  102. // Left implements Comparer interface
  103. func (c *comparison) Left() sql.Expression { return c.BinaryExpression.Left }
  104. // Right implements Comparer interface
  105. func (c *comparison) Right() sql.Expression { return c.BinaryExpression.Right }
  106. // Equals is a comparison that checks an expression is equal to another.
  107. type Equals struct {
  108. comparison
  109. }
  110. // NewEquals returns a new Equals expression.
  111. func NewEquals(left sql.Expression, right sql.Expression) *Equals {
  112. return &Equals{newComparison(left, right)}
  113. }
  114. // Eval implements the Expression interface.
  115. func (e *Equals) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  116. result, err := e.Compare(ctx, row)
  117. if err != nil {
  118. if ErrNilOperand.Is(err) {
  119. return nil, nil
  120. }
  121. return nil, err
  122. }
  123. return result == 0, nil
  124. }
  125. // TransformUp implements the Expression interface.
  126. func (e *Equals) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  127. left, err := e.Left().TransformUp(f)
  128. if err != nil {
  129. return nil, err
  130. }
  131. right, err := e.Right().TransformUp(f)
  132. if err != nil {
  133. return nil, err
  134. }
  135. return f(NewEquals(left, right))
  136. }
  137. func (e *Equals) String() string {
  138. return fmt.Sprintf("%s = %s", e.Left(), e.Right())
  139. }
  140. // Regexp is a comparison that checks an expression matches a regexp.
  141. type Regexp struct {
  142. comparison
  143. r regex.Matcher
  144. }
  145. // NewRegexp creates a new Regexp expression.
  146. func NewRegexp(left sql.Expression, right sql.Expression) *Regexp {
  147. return &Regexp{newComparison(left, right), nil}
  148. }
  149. // Eval implements the Expression interface.
  150. func (re *Regexp) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  151. if sql.IsText(re.Left().Type()) && sql.IsText(re.Right().Type()) {
  152. return re.compareRegexp(ctx, row)
  153. }
  154. result, err := re.Compare(ctx, row)
  155. if err != nil {
  156. if ErrNilOperand.Is(err) {
  157. return nil, nil
  158. }
  159. return nil, err
  160. }
  161. return result == 0, nil
  162. }
  163. func (re *Regexp) compareRegexp(ctx *sql.Context, row sql.Row) (interface{}, error) {
  164. left, right, err := re.evalLeftAndRight(ctx, row)
  165. if err != nil {
  166. return nil, err
  167. }
  168. if left == nil || right == nil {
  169. return nil, nil
  170. }
  171. left, err = sql.Text.Convert(left)
  172. if err != nil {
  173. return nil, err
  174. }
  175. right, err = sql.Text.Convert(right)
  176. if err != nil {
  177. return nil, err
  178. }
  179. if re.r == nil {
  180. re.r, err = regex.New(regex.Default(), right.(string))
  181. if err != nil {
  182. return false, err
  183. }
  184. }
  185. return re.r.Match(left.(string)), nil
  186. }
  187. // TransformUp implements the Expression interface.
  188. func (re *Regexp) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  189. left, err := re.Left().TransformUp(f)
  190. if err != nil {
  191. return nil, err
  192. }
  193. right, err := re.Right().TransformUp(f)
  194. if err != nil {
  195. return nil, err
  196. }
  197. return f(NewRegexp(left, right))
  198. }
  199. func (re *Regexp) String() string {
  200. return fmt.Sprintf("%s REGEXP %s", re.Left(), re.Right())
  201. }
  202. // GreaterThan is a comparison that checks an expression is greater than another.
  203. type GreaterThan struct {
  204. comparison
  205. }
  206. // NewGreaterThan creates a new GreaterThan expression.
  207. func NewGreaterThan(left sql.Expression, right sql.Expression) *GreaterThan {
  208. return &GreaterThan{newComparison(left, right)}
  209. }
  210. // Eval implements the Expression interface.
  211. func (gt *GreaterThan) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  212. result, err := gt.Compare(ctx, row)
  213. if err != nil {
  214. if ErrNilOperand.Is(err) {
  215. return nil, nil
  216. }
  217. return nil, err
  218. }
  219. return result == 1, nil
  220. }
  221. // TransformUp implements the Expression interface.
  222. func (gt *GreaterThan) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  223. left, err := gt.Left().TransformUp(f)
  224. if err != nil {
  225. return nil, err
  226. }
  227. right, err := gt.Right().TransformUp(f)
  228. if err != nil {
  229. return nil, err
  230. }
  231. return f(NewGreaterThan(left, right))
  232. }
  233. func (gt *GreaterThan) String() string {
  234. return fmt.Sprintf("%s > %s", gt.Left(), gt.Right())
  235. }
  236. // LessThan is a comparison that checks an expression is less than another.
  237. type LessThan struct {
  238. comparison
  239. }
  240. // NewLessThan creates a new LessThan expression.
  241. func NewLessThan(left sql.Expression, right sql.Expression) *LessThan {
  242. return &LessThan{newComparison(left, right)}
  243. }
  244. // Eval implements the expression interface.
  245. func (lt *LessThan) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  246. result, err := lt.Compare(ctx, row)
  247. if err != nil {
  248. if ErrNilOperand.Is(err) {
  249. return nil, nil
  250. }
  251. return nil, err
  252. }
  253. return result == -1, nil
  254. }
  255. // TransformUp implements the Expression interface.
  256. func (lt *LessThan) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  257. left, err := lt.Left().TransformUp(f)
  258. if err != nil {
  259. return nil, err
  260. }
  261. right, err := lt.Right().TransformUp(f)
  262. if err != nil {
  263. return nil, err
  264. }
  265. return f(NewLessThan(left, right))
  266. }
  267. func (lt *LessThan) String() string {
  268. return fmt.Sprintf("%s < %s", lt.Left(), lt.Right())
  269. }
  270. // GreaterThanOrEqual is a comparison that checks an expression is greater or equal to
  271. // another.
  272. type GreaterThanOrEqual struct {
  273. comparison
  274. }
  275. // NewGreaterThanOrEqual creates a new GreaterThanOrEqual
  276. func NewGreaterThanOrEqual(left sql.Expression, right sql.Expression) *GreaterThanOrEqual {
  277. return &GreaterThanOrEqual{newComparison(left, right)}
  278. }
  279. // Eval implements the Expression interface.
  280. func (gte *GreaterThanOrEqual) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  281. result, err := gte.Compare(ctx, row)
  282. if err != nil {
  283. if ErrNilOperand.Is(err) {
  284. return nil, nil
  285. }
  286. return nil, err
  287. }
  288. return result > -1, nil
  289. }
  290. // TransformUp implements the Expression interface.
  291. func (gte *GreaterThanOrEqual) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  292. left, err := gte.Left().TransformUp(f)
  293. if err != nil {
  294. return nil, err
  295. }
  296. right, err := gte.Right().TransformUp(f)
  297. if err != nil {
  298. return nil, err
  299. }
  300. return f(NewGreaterThanOrEqual(left, right))
  301. }
  302. func (gte *GreaterThanOrEqual) String() string {
  303. return fmt.Sprintf("%s >= %s", gte.Left(), gte.Right())
  304. }
  305. // LessThanOrEqual is a comparison that checks an expression is equal or lower than
  306. // another.
  307. type LessThanOrEqual struct {
  308. comparison
  309. }
  310. // NewLessThanOrEqual creates a LessThanOrEqual expression.
  311. func NewLessThanOrEqual(left sql.Expression, right sql.Expression) *LessThanOrEqual {
  312. return &LessThanOrEqual{newComparison(left, right)}
  313. }
  314. // Eval implements the Expression interface.
  315. func (lte *LessThanOrEqual) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  316. result, err := lte.Compare(ctx, row)
  317. if err != nil {
  318. if ErrNilOperand.Is(err) {
  319. return nil, nil
  320. }
  321. return nil, err
  322. }
  323. return result < 1, nil
  324. }
  325. // TransformUp implements the Expression interface.
  326. func (lte *LessThanOrEqual) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  327. left, err := lte.Left().TransformUp(f)
  328. if err != nil {
  329. return nil, err
  330. }
  331. right, err := lte.Right().TransformUp(f)
  332. if err != nil {
  333. return nil, err
  334. }
  335. return f(NewLessThanOrEqual(left, right))
  336. }
  337. func (lte *LessThanOrEqual) String() string {
  338. return fmt.Sprintf("%s <= %s", lte.Left(), lte.Right())
  339. }
  340. var (
  341. // ErrUnsupportedInOperand is returned when there is an invalid righthand
  342. // operand in an IN operator.
  343. ErrUnsupportedInOperand = errors.NewKind("right operand in IN operation must be tuple, but is %T")
  344. // ErrInvalidOperandColumns is returned when the columns in the left operand
  345. // and the elements of the right operand don't match.
  346. ErrInvalidOperandColumns = errors.NewKind("operand should have %d columns, but has %d")
  347. )
  348. // In is a comparison that checks an expression is inside a list of expressions.
  349. type In struct {
  350. comparison
  351. }
  352. // NewIn creates a In expression.
  353. func NewIn(left sql.Expression, right sql.Expression) *In {
  354. return &In{newComparison(left, right)}
  355. }
  356. // Eval implements the Expression interface.
  357. func (in *In) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  358. typ := in.Left().Type()
  359. leftElems := sql.NumColumns(typ)
  360. left, err := in.Left().Eval(ctx, row)
  361. if err != nil {
  362. return nil, err
  363. }
  364. if left == nil {
  365. return nil, err
  366. }
  367. left, err = typ.Convert(left)
  368. if err != nil {
  369. return nil, err
  370. }
  371. // TODO: support subqueries
  372. switch right := in.Right().(type) {
  373. case Tuple:
  374. for _, el := range right {
  375. if sql.NumColumns(el.Type()) != leftElems {
  376. return nil, ErrInvalidOperandColumns.New(leftElems, sql.NumColumns(el.Type()))
  377. }
  378. }
  379. for _, el := range right {
  380. right, err := el.Eval(ctx, row)
  381. if err != nil {
  382. return nil, err
  383. }
  384. right, err = typ.Convert(right)
  385. if err != nil {
  386. return nil, err
  387. }
  388. cmp, err := typ.Compare(left, right)
  389. if err != nil {
  390. return nil, err
  391. }
  392. if cmp == 0 {
  393. return true, nil
  394. }
  395. }
  396. return false, nil
  397. default:
  398. return nil, ErrUnsupportedInOperand.New(right)
  399. }
  400. }
  401. // TransformUp implements the Expression interface.
  402. func (in *In) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  403. left, err := in.Left().TransformUp(f)
  404. if err != nil {
  405. return nil, err
  406. }
  407. right, err := in.Right().TransformUp(f)
  408. if err != nil {
  409. return nil, err
  410. }
  411. return f(NewIn(left, right))
  412. }
  413. func (in *In) String() string {
  414. return fmt.Sprintf("%s IN %s", in.Left(), in.Right())
  415. }
  416. // Children implements the Expression interface.
  417. func (in *In) Children() []sql.Expression {
  418. return []sql.Expression{in.Left(), in.Right()}
  419. }
  420. // NotIn is a comparison that checks an expression is not inside a list of expressions.
  421. type NotIn struct {
  422. comparison
  423. }
  424. // NewNotIn creates a In expression.
  425. func NewNotIn(left sql.Expression, right sql.Expression) *NotIn {
  426. return &NotIn{newComparison(left, right)}
  427. }
  428. // Eval implements the Expression interface.
  429. func (in *NotIn) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
  430. typ := in.Left().Type()
  431. leftElems := sql.NumColumns(typ)
  432. left, err := in.Left().Eval(ctx, row)
  433. if err != nil {
  434. return nil, err
  435. }
  436. if left == nil {
  437. return nil, err
  438. }
  439. left, err = typ.Convert(left)
  440. if err != nil {
  441. return nil, err
  442. }
  443. // TODO: support subqueries
  444. switch right := in.Right().(type) {
  445. case Tuple:
  446. for _, el := range right {
  447. if sql.NumColumns(el.Type()) != leftElems {
  448. return nil, ErrInvalidOperandColumns.New(leftElems, sql.NumColumns(el.Type()))
  449. }
  450. }
  451. for _, el := range right {
  452. right, err := el.Eval(ctx, row)
  453. if err != nil {
  454. return nil, err
  455. }
  456. right, err = typ.Convert(right)
  457. if err != nil {
  458. return nil, err
  459. }
  460. cmp, err := typ.Compare(left, right)
  461. if err != nil {
  462. return nil, err
  463. }
  464. if cmp == 0 {
  465. return false, nil
  466. }
  467. }
  468. return true, nil
  469. default:
  470. return nil, ErrUnsupportedInOperand.New(right)
  471. }
  472. }
  473. // TransformUp implements the Expression interface.
  474. func (in *NotIn) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
  475. left, err := in.Left().TransformUp(f)
  476. if err != nil {
  477. return nil, err
  478. }
  479. right, err := in.Right().TransformUp(f)
  480. if err != nil {
  481. return nil, err
  482. }
  483. return f(NewNotIn(left, right))
  484. }
  485. func (in *NotIn) String() string {
  486. return fmt.Sprintf("%s NOT IN %s", in.Left(), in.Right())
  487. }
  488. // Children implements the Expression interface.
  489. func (in *NotIn) Children() []sql.Expression {
  490. return []sql.Expression{in.Left(), in.Right()}
  491. }