valuer_eval_test.go 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package xsql
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/emqx/kuiper/common"
  6. "reflect"
  7. "strings"
  8. "testing"
  9. )
  10. func TestComparison(t *testing.T) {
  11. testTime, _ := common.InterfaceToTime(1541152488442, "")
  12. data := []struct {
  13. m Message
  14. r []interface{}
  15. }{
  16. {
  17. m: map[string]interface{}{
  18. "a": float64(32),
  19. "b": float64(72),
  20. },
  21. r: []interface{}{
  22. false, true, errors.New("invalid operation float64(32) = string(string literal)"),
  23. false, true, false, true,
  24. },
  25. }, {
  26. m: map[string]interface{}{
  27. "a": int64(32),
  28. "b": int64(72),
  29. },
  30. r: []interface{}{
  31. false, true, errors.New("invalid operation int64(32) = string(string literal)"),
  32. false, true, false, true,
  33. },
  34. }, {
  35. m: map[string]interface{}{
  36. "a": "32",
  37. "b": "72",
  38. },
  39. r: []interface{}{
  40. errors.New("invalid operation string(32) > int64(72)"), errors.New("invalid operation string(32) <= int64(32)"), false,
  41. false, true, false, true,
  42. },
  43. }, {
  44. m: map[string]interface{}{
  45. "a": []interface{}{32, 72},
  46. "b": []interface{}{32, 72},
  47. },
  48. r: []interface{}{
  49. errors.New("> is an invalid operation for []interface {}"), errors.New("<= is an invalid operation for []interface {}"), errors.New("= is an invalid operation for []interface {}"),
  50. errors.New(">= is an invalid operation for []interface {}"), errors.New("< is an invalid operation for []interface {}"), errors.New("= is an invalid operation for []interface {}"), errors.New("!= is an invalid operation for []interface {}"),
  51. },
  52. }, {
  53. m: map[string]interface{}{
  54. "a": map[string]interface{}{"c": 5},
  55. "b": map[string]interface{}{"d": 5},
  56. },
  57. r: []interface{}{
  58. errors.New("> is an invalid operation for map[string]interface {}"), errors.New("<= is an invalid operation for map[string]interface {}"), errors.New("= is an invalid operation for map[string]interface {}"),
  59. errors.New(">= is an invalid operation for map[string]interface {}"), errors.New("< is an invalid operation for map[string]interface {}"), errors.New("= is an invalid operation for map[string]interface {}"), errors.New("!= is an invalid operation for map[string]interface {}"),
  60. },
  61. }, {
  62. m: map[string]interface{}{
  63. "a": float64(55),
  64. "b": int64(55),
  65. },
  66. r: []interface{}{
  67. false, false, errors.New("invalid operation float64(55) = string(string literal)"),
  68. true, false, true, false,
  69. },
  70. }, {
  71. m: map[string]interface{}{
  72. "a": testTime,
  73. "b": int64(1541152388442),
  74. },
  75. r: []interface{}{
  76. true, false, errors.New("invalid operation time.Time(2018-11-02 09:54:48.442 +0000 UTC) = string(string literal)"),
  77. true, false, false, true,
  78. },
  79. }, {
  80. m: map[string]interface{}{
  81. "a": testTime,
  82. "b": "2020-02-26T02:37:21.822Z",
  83. },
  84. r: []interface{}{
  85. true, false, errors.New("invalid operation time.Time(2018-11-02 09:54:48.442 +0000 UTC) = string(string literal)"),
  86. false, true, false, true,
  87. },
  88. }, {
  89. m: map[string]interface{}{
  90. "a": int64(1541152388442),
  91. "b": testTime,
  92. },
  93. r: []interface{}{
  94. true, false, errors.New("invalid operation int64(1541152388442) = string(string literal)"),
  95. errors.New("invalid operation int64(1541152388442) >= time.Time(2018-11-02 09:54:48.442 +0000 UTC)"), errors.New("invalid operation int64(1541152388442) < time.Time(2018-11-02 09:54:48.442 +0000 UTC)"), errors.New("invalid operation int64(1541152388442) = time.Time(2018-11-02 09:54:48.442 +0000 UTC)"), errors.New("invalid operation int64(1541152388442) != time.Time(2018-11-02 09:54:48.442 +0000 UTC)"),
  96. },
  97. }, {
  98. m: map[string]interface{}{
  99. "a": "2020-02-26T02:37:21.822Z",
  100. "b": testTime,
  101. },
  102. r: []interface{}{
  103. errors.New("invalid operation string(2020-02-26T02:37:21.822Z) > int64(72)"), errors.New("invalid operation string(2020-02-26T02:37:21.822Z) <= int64(32)"), false,
  104. errors.New("invalid operation string(2020-02-26T02:37:21.822Z) >= time.Time(2018-11-02 09:54:48.442 +0000 UTC)"), errors.New("invalid operation string(2020-02-26T02:37:21.822Z) < time.Time(2018-11-02 09:54:48.442 +0000 UTC)"), errors.New("invalid operation string(2020-02-26T02:37:21.822Z) = time.Time(2018-11-02 09:54:48.442 +0000 UTC)"), errors.New("invalid operation string(2020-02-26T02:37:21.822Z) != time.Time(2018-11-02 09:54:48.442 +0000 UTC)"),
  105. },
  106. }, {
  107. m: map[string]interface{}{
  108. "c": "nothing",
  109. },
  110. r: []interface{}{
  111. false, false, false,
  112. true, false, true, false,
  113. },
  114. }, {
  115. m: map[string]interface{}{
  116. "a": 12,
  117. "c": "nothing",
  118. },
  119. r: []interface{}{
  120. false, true, errors.New("invalid operation int64(12) = string(string literal)"),
  121. false, false, false, true,
  122. },
  123. },
  124. }
  125. sqls := []string{
  126. "select * from src where a > 72",
  127. "select * from src where a <= 32",
  128. "select * from src where a = \"string literal\"",
  129. "select * from src where a >= b",
  130. "select * from src where a < b",
  131. "select * from src where a = b",
  132. "select * from src where a != b",
  133. }
  134. var conditions []Expr
  135. for _, sql := range sqls {
  136. stmt, _ := NewParser(strings.NewReader(sql)).Parse()
  137. conditions = append(conditions, stmt.Condition)
  138. }
  139. fmt.Printf("The test bucket size is %d.\n\n", len(data)*len(sqls))
  140. for i, tt := range data {
  141. for j, c := range conditions {
  142. tuple := &Tuple{Emitter: "src", Message: tt.m, Timestamp: common.GetNowInMilli(), Metadata: nil}
  143. ve := &ValuerEval{Valuer: MultiValuer(tuple)}
  144. result := ve.Eval(c)
  145. if !reflect.DeepEqual(tt.r[j], result) {
  146. t.Errorf("%d-%d. \nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.r[j], result)
  147. }
  148. }
  149. }
  150. }
  151. func TestCalculation(t *testing.T) {
  152. data := []struct {
  153. m Message
  154. r []interface{}
  155. }{
  156. {
  157. m: map[string]interface{}{
  158. "a": float64(32),
  159. "b": float64(72),
  160. },
  161. r: []interface{}{
  162. float64(104), float64(96), float64(0.4444444444444444), float64(32),
  163. },
  164. }, {
  165. m: map[string]interface{}{
  166. "a": int64(32),
  167. "b": int64(72),
  168. },
  169. r: []interface{}{
  170. int64(104), int64(96), int64(0), int64(32),
  171. },
  172. }, {
  173. m: map[string]interface{}{
  174. "a": "32",
  175. "b": "72",
  176. },
  177. r: []interface{}{
  178. errors.New("invalid operation string(32) + string(72)"), errors.New("invalid operation string(32) * int64(3)"),
  179. errors.New("invalid operation string(32) / string(72)"), errors.New("invalid operation string(32) % string(72)"),
  180. },
  181. }, {
  182. m: map[string]interface{}{
  183. "a": float64(55),
  184. "b": int64(55),
  185. },
  186. r: []interface{}{
  187. float64(110), float64(165), float64(1), float64(0),
  188. },
  189. }, {
  190. m: map[string]interface{}{
  191. "a": int64(55),
  192. "b": float64(0),
  193. },
  194. r: []interface{}{
  195. float64(55), int64(165), errors.New("divided by zero"), errors.New("divided by zero"),
  196. },
  197. }, {
  198. m: map[string]interface{}{
  199. "c": "nothing",
  200. },
  201. r: []interface{}{
  202. nil, nil, nil, nil,
  203. },
  204. }, {
  205. m: map[string]interface{}{
  206. "a": 12,
  207. "c": "nothing",
  208. },
  209. r: []interface{}{
  210. nil, int64(36), nil, nil,
  211. },
  212. },
  213. }
  214. sqls := []string{
  215. "select a + b as t from src",
  216. "select a * 3 as t from src",
  217. "select a / b as t from src",
  218. "select a % b as t from src",
  219. }
  220. var projects []Expr
  221. for _, sql := range sqls {
  222. stmt, _ := NewParser(strings.NewReader(sql)).Parse()
  223. projects = append(projects, stmt.Fields[0].Expr)
  224. }
  225. fmt.Printf("The test bucket size is %d.\n\n", len(data)*len(sqls))
  226. for i, tt := range data {
  227. for j, c := range projects {
  228. tuple := &Tuple{Emitter: "src", Message: tt.m, Timestamp: common.GetNowInMilli(), Metadata: nil}
  229. ve := &ValuerEval{Valuer: MultiValuer(tuple)}
  230. result := ve.Eval(c)
  231. if !reflect.DeepEqual(tt.r[j], result) {
  232. t.Errorf("%d-%d. \nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.r[j], result)
  233. }
  234. }
  235. }
  236. }