valuer_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. // Copyright 2021 EMQ Technologies Co., Ltd.
  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. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package xsql
  15. import (
  16. "errors"
  17. "fmt"
  18. "github.com/lf-edge/ekuiper/internal/conf"
  19. "github.com/lf-edge/ekuiper/pkg/ast"
  20. "github.com/lf-edge/ekuiper/pkg/cast"
  21. "reflect"
  22. "strings"
  23. "testing"
  24. )
  25. func TestComparison(t *testing.T) {
  26. testTime, _ := cast.InterfaceToTime(1541152488442, "")
  27. data := []struct {
  28. m Message
  29. r []interface{}
  30. }{
  31. {
  32. m: map[string]interface{}{
  33. "a": float64(32),
  34. "b": float64(72),
  35. },
  36. r: []interface{}{
  37. false, true, errors.New("invalid operation float64(32) = string(string literal)"),
  38. false, true, false, true,
  39. },
  40. }, {
  41. m: map[string]interface{}{
  42. "a": int64(32),
  43. "b": int64(72),
  44. },
  45. r: []interface{}{
  46. false, true, errors.New("invalid operation int64(32) = string(string literal)"),
  47. false, true, false, true,
  48. },
  49. }, {
  50. m: map[string]interface{}{
  51. "a": "32",
  52. "b": "72",
  53. },
  54. r: []interface{}{
  55. errors.New("invalid operation string(32) > int64(72)"), errors.New("invalid operation string(32) <= int64(32)"), false,
  56. false, true, false, true,
  57. },
  58. }, {
  59. m: map[string]interface{}{
  60. "a": []interface{}{32, 72},
  61. "b": []interface{}{32, 72},
  62. },
  63. r: []interface{}{
  64. errors.New("> is an invalid operation for []interface {}"), errors.New("<= is an invalid operation for []interface {}"), errors.New("= is an invalid operation for []interface {}"),
  65. 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 {}"),
  66. },
  67. }, {
  68. m: map[string]interface{}{
  69. "a": map[string]interface{}{"c": 5},
  70. "b": map[string]interface{}{"d": 5},
  71. },
  72. r: []interface{}{
  73. 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 {}"),
  74. 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 {}"),
  75. },
  76. }, {
  77. m: map[string]interface{}{
  78. "a": float64(55),
  79. "b": int64(55),
  80. },
  81. r: []interface{}{
  82. false, false, errors.New("invalid operation float64(55) = string(string literal)"),
  83. true, false, true, false,
  84. },
  85. }, {
  86. m: map[string]interface{}{
  87. "a": testTime,
  88. "b": int64(1541152388442),
  89. },
  90. r: []interface{}{
  91. true, false, errors.New("invalid operation time.Time(2018-11-02 09:54:48.442 +0000 UTC) = string(string literal)"),
  92. true, false, false, true,
  93. },
  94. }, {
  95. m: map[string]interface{}{
  96. "a": testTime,
  97. "b": "2020-02-26T02:37:21.822Z",
  98. },
  99. r: []interface{}{
  100. true, false, errors.New("invalid operation time.Time(2018-11-02 09:54:48.442 +0000 UTC) = string(string literal)"),
  101. false, true, false, true,
  102. },
  103. }, {
  104. m: map[string]interface{}{
  105. "a": int64(1541152388442),
  106. "b": testTime,
  107. },
  108. r: []interface{}{
  109. true, false, errors.New("invalid operation int64(1541152388442) = string(string literal)"),
  110. 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)"),
  111. },
  112. }, {
  113. m: map[string]interface{}{
  114. "a": "2020-02-26T02:37:21.822Z",
  115. "b": testTime,
  116. },
  117. r: []interface{}{
  118. 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,
  119. 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)"),
  120. },
  121. }, {
  122. m: map[string]interface{}{
  123. "c": "nothing",
  124. },
  125. r: []interface{}{
  126. false, false, false,
  127. true, false, true, false,
  128. },
  129. }, {
  130. m: map[string]interface{}{
  131. "a": 12,
  132. "c": "nothing",
  133. },
  134. r: []interface{}{
  135. false, true, errors.New("invalid operation int64(12) = string(string literal)"),
  136. false, false, false, true,
  137. },
  138. },
  139. }
  140. sqls := []string{
  141. "select * from src where a > 72",
  142. "select * from src where a <= 32",
  143. "select * from src where a = \"string literal\"",
  144. "select * from src where a >= b",
  145. "select * from src where a < b",
  146. "select * from src where a = b",
  147. "select * from src where a != b",
  148. }
  149. var conditions []ast.Expr
  150. for _, sql := range sqls {
  151. stmt, _ := NewParser(strings.NewReader(sql)).Parse()
  152. conditions = append(conditions, stmt.Condition)
  153. }
  154. fmt.Printf("The test bucket size is %d.\n\n", len(data)*len(sqls))
  155. for i, tt := range data {
  156. for j, c := range conditions {
  157. tuple := &Tuple{Emitter: "src", Message: tt.m, Timestamp: conf.GetNowInMilli(), Metadata: nil}
  158. ve := &ValuerEval{Valuer: MultiValuer(tuple)}
  159. result := ve.Eval(c)
  160. if !reflect.DeepEqual(tt.r[j], result) {
  161. t.Errorf("%d-%d. \nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.r[j], result)
  162. }
  163. }
  164. }
  165. }
  166. func TestCalculation(t *testing.T) {
  167. data := []struct {
  168. m Message
  169. r []interface{}
  170. }{
  171. {
  172. m: map[string]interface{}{
  173. "a": float64(32),
  174. "b": float64(72),
  175. },
  176. r: []interface{}{
  177. float64(104), float64(96), float64(0.4444444444444444), float64(32),
  178. },
  179. }, {
  180. m: map[string]interface{}{
  181. "a": int64(32),
  182. "b": int64(72),
  183. },
  184. r: []interface{}{
  185. int64(104), int64(96), int64(0), int64(32),
  186. },
  187. }, {
  188. m: map[string]interface{}{
  189. "a": "32",
  190. "b": "72",
  191. },
  192. r: []interface{}{
  193. errors.New("invalid operation string(32) + string(72)"), errors.New("invalid operation string(32) * int64(3)"),
  194. errors.New("invalid operation string(32) / string(72)"), errors.New("invalid operation string(32) % string(72)"),
  195. },
  196. }, {
  197. m: map[string]interface{}{
  198. "a": float64(55),
  199. "b": int64(55),
  200. },
  201. r: []interface{}{
  202. float64(110), float64(165), float64(1), float64(0),
  203. },
  204. }, {
  205. m: map[string]interface{}{
  206. "a": int64(55),
  207. "b": float64(0),
  208. },
  209. r: []interface{}{
  210. float64(55), int64(165), errors.New("divided by zero"), errors.New("divided by zero"),
  211. },
  212. }, {
  213. m: map[string]interface{}{
  214. "c": "nothing",
  215. },
  216. r: []interface{}{
  217. nil, nil, nil, nil,
  218. },
  219. }, {
  220. m: map[string]interface{}{
  221. "a": 12,
  222. "c": "nothing",
  223. },
  224. r: []interface{}{
  225. nil, int64(36), nil, nil,
  226. },
  227. },
  228. }
  229. sqls := []string{
  230. "select a + b as t from src",
  231. "select a * 3 as t from src",
  232. "select a / b as t from src",
  233. "select a % b as t from src",
  234. }
  235. var projects []ast.Expr
  236. for _, sql := range sqls {
  237. stmt, _ := NewParser(strings.NewReader(sql)).Parse()
  238. projects = append(projects, stmt.Fields[0].Expr)
  239. }
  240. fmt.Printf("The test bucket size is %d.\n\n", len(data)*len(sqls))
  241. for i, tt := range data {
  242. for j, c := range projects {
  243. tuple := &Tuple{Emitter: "src", Message: tt.m, Timestamp: conf.GetNowInMilli(), Metadata: nil}
  244. ve := &ValuerEval{Valuer: MultiValuer(tuple)}
  245. result := ve.Eval(c)
  246. if !reflect.DeepEqual(tt.r[j], result) {
  247. t.Errorf("%d-%d. \nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.r[j], result)
  248. }
  249. }
  250. }
  251. }
  252. func TestCase(t *testing.T) {
  253. data := []struct {
  254. m Message
  255. r []interface{}
  256. }{
  257. {
  258. m: map[string]interface{}{
  259. "a": float64(32),
  260. "b": float64(72),
  261. },
  262. r: []interface{}{
  263. 1, 0, 0, 1,
  264. },
  265. }, {
  266. m: map[string]interface{}{
  267. "a": int64(32),
  268. "b": int64(72),
  269. },
  270. r: []interface{}{
  271. 1, 0, 0, 1,
  272. },
  273. }, {
  274. m: map[string]interface{}{
  275. "a": "32",
  276. "b": "72",
  277. },
  278. r: []interface{}{
  279. errors.New("evaluate case expression error: invalid operation string(32) = int64(32)"), errors.New("evaluate case expression error: invalid operation string(32) = int64(72)"),
  280. errors.New("evaluate case expression error: invalid operation string(32) > int64(70)"), errors.New("evaluate case expression error: invalid operation string(32) > int64(30)"),
  281. },
  282. }, {
  283. m: map[string]interface{}{
  284. "a": float64(55),
  285. "b": int64(55),
  286. },
  287. r: []interface{}{
  288. 0, nil, 0, 1,
  289. },
  290. }, {
  291. m: map[string]interface{}{
  292. "a": int64(55),
  293. "b": float64(0),
  294. },
  295. r: []interface{}{0, nil, 0, 1},
  296. }, {
  297. m: map[string]interface{}{
  298. "c": "nothing",
  299. },
  300. r: []interface{}{
  301. 0, nil, -1, nil,
  302. },
  303. }, {
  304. m: map[string]interface{}{
  305. "a": 12,
  306. "c": "nothing",
  307. },
  308. r: []interface{}{
  309. 0, nil, -1, nil,
  310. },
  311. },
  312. }
  313. sqls := []string{
  314. "select CASE a WHEN 32 THEN 1 ELSE 0 END as t from src",
  315. "select CASE a WHEN 72 THEN 1 WHEN 32 THEN 0 END as t from src",
  316. "select CASE WHEN a > 70 THEN 1 WHEN a > 30 AND a < 70 THEN 0 ELSE -1 END as t from src",
  317. "select CASE WHEN a > 30 THEN 1 END as t from src",
  318. }
  319. var projects []ast.Expr
  320. for _, sql := range sqls {
  321. stmt, _ := NewParser(strings.NewReader(sql)).Parse()
  322. projects = append(projects, stmt.Fields[0].Expr)
  323. }
  324. fmt.Printf("The test bucket size is %d.\n\n", len(data)*len(sqls))
  325. for i, tt := range data {
  326. for j, c := range projects {
  327. tuple := &Tuple{Emitter: "src", Message: tt.m, Timestamp: conf.GetNowInMilli(), Metadata: nil}
  328. ve := &ValuerEval{Valuer: MultiValuer(tuple)}
  329. result := ve.Eval(c)
  330. if !reflect.DeepEqual(tt.r[j], result) {
  331. t.Errorf("%d-%d. \nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.r[j], result)
  332. }
  333. }
  334. }
  335. }
  336. func TestArray(t *testing.T) {
  337. data := []struct {
  338. m Message
  339. r []interface{}
  340. }{
  341. {
  342. m: map[string]interface{}{
  343. "a": []int64{0, 1, 2, 3, 4, 5},
  344. },
  345. r: []interface{}{
  346. int64(0), int64(5), int64(1), []int64{0, 1}, []int64{4, 5}, []int64{5}, []int64{0, 1, 2, 3, 4}, []int64{1, 2, 3, 4}, []int64{0, 1, 2, 3, 4, 5},
  347. },
  348. },
  349. }
  350. sqls := []string{
  351. "select a[0] as t from src",
  352. "select a[-1] as t from src",
  353. "select a[1] as t from src",
  354. "select a[:2] as t from src",
  355. "select a[4:] as t from src",
  356. "select a[-1:] as t from src",
  357. "select a[0:-1] as t from src",
  358. "select a[-5:-1] as t from src",
  359. "select a[:] as t from src",
  360. }
  361. var projects []ast.Expr
  362. for _, sql := range sqls {
  363. stmt, _ := NewParser(strings.NewReader(sql)).Parse()
  364. projects = append(projects, stmt.Fields[0].Expr)
  365. }
  366. fmt.Printf("The test bucket size is %d.\n\n", len(data)*len(sqls))
  367. for i, tt := range data {
  368. for j, c := range projects {
  369. tuple := &Tuple{Emitter: "src", Message: tt.m, Timestamp: conf.GetNowInMilli(), Metadata: nil}
  370. ve := &ValuerEval{Valuer: MultiValuer(tuple)}
  371. result := ve.Eval(c)
  372. if !reflect.DeepEqual(tt.r[j], result) {
  373. t.Errorf("%d-%d. \nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, j, tt.r[j], result)
  374. }
  375. }
  376. }
  377. }