math_func_test.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. package plans
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/emqx/kuiper/common"
  6. "github.com/emqx/kuiper/xsql"
  7. "github.com/emqx/kuiper/xstream/contexts"
  8. "reflect"
  9. "strings"
  10. "testing"
  11. )
  12. func TestMathAndConversionFunc_Apply1(t *testing.T) {
  13. var tests = []struct {
  14. sql string
  15. data *xsql.Tuple
  16. result []map[string]interface{}
  17. }{
  18. {
  19. sql: "SELECT abs(a) AS a FROM test",
  20. data: &xsql.Tuple{
  21. Emitter: "test",
  22. Message: xsql.Message{
  23. "a": -1,
  24. },
  25. },
  26. result: []map[string]interface{}{{
  27. "a": float64(1), //Actually it should be 1, it's caused by json Unmarshal method, which convert int to float64
  28. }},
  29. },
  30. {
  31. sql: "SELECT abs(a) AS a FROM test",
  32. data: &xsql.Tuple{
  33. Emitter: "test",
  34. Message: xsql.Message{
  35. "a": -1.1,
  36. },
  37. },
  38. result: []map[string]interface{}{{
  39. "a": 1.1,
  40. }},
  41. },
  42. {
  43. sql: "SELECT abs(a) AS a FROM test",
  44. data: &xsql.Tuple{
  45. Emitter: "test",
  46. Message: xsql.Message{
  47. "a": 1.1,
  48. },
  49. },
  50. result: []map[string]interface{}{{
  51. "a": 1.1,
  52. }},
  53. },
  54. {
  55. sql: "SELECT acos(1) AS a FROM test",
  56. data: &xsql.Tuple{
  57. Emitter: "test",
  58. Message: nil,
  59. },
  60. result: []map[string]interface{}{{
  61. "a": float64(0),
  62. }},
  63. },
  64. {
  65. sql: "SELECT asin(1) AS a FROM test",
  66. data: &xsql.Tuple{
  67. Emitter: "test",
  68. Message: nil,
  69. },
  70. result: []map[string]interface{}{{
  71. "a": float64(1.5707963267948966),
  72. }},
  73. },
  74. {
  75. sql: "SELECT atan(1) AS a FROM test",
  76. data: &xsql.Tuple{
  77. Emitter: "test",
  78. Message: nil,
  79. },
  80. result: []map[string]interface{}{{
  81. "a": float64(0.7853981633974483),
  82. }},
  83. },
  84. {
  85. sql: "SELECT atan2(1,1) AS a FROM test",
  86. data: &xsql.Tuple{
  87. Emitter: "test",
  88. Message: nil,
  89. },
  90. result: []map[string]interface{}{{
  91. "a": float64(0.7853981633974483),
  92. }},
  93. },
  94. {
  95. sql: "SELECT bitand(1,1) AS a FROM test",
  96. data: &xsql.Tuple{
  97. Emitter: "test",
  98. Message: nil,
  99. },
  100. result: []map[string]interface{}{{
  101. "a": float64(1),
  102. }},
  103. },
  104. {
  105. sql: "SELECT bitand(1.0,1) AS a FROM test",
  106. data: &xsql.Tuple{
  107. Emitter: "test",
  108. Message: nil,
  109. },
  110. result: nil,
  111. },
  112. {
  113. sql: "SELECT bitor(1,1) AS a FROM test",
  114. data: &xsql.Tuple{
  115. Emitter: "test",
  116. Message: nil,
  117. },
  118. result: []map[string]interface{}{{
  119. "a": float64(1),
  120. }},
  121. },
  122. {
  123. sql: "SELECT bitxor(1,1) AS a FROM test",
  124. data: &xsql.Tuple{
  125. Emitter: "test",
  126. Message: nil,
  127. },
  128. result: []map[string]interface{}{{
  129. "a": float64(0),
  130. }},
  131. },
  132. {
  133. sql: "SELECT bitnot(1) AS a FROM test",
  134. data: &xsql.Tuple{
  135. Emitter: "test",
  136. Message: nil,
  137. },
  138. result: []map[string]interface{}{{
  139. "a": float64(-2),
  140. }},
  141. },
  142. {
  143. sql: "SELECT ceil(1.6) AS a FROM test",
  144. data: &xsql.Tuple{
  145. Emitter: "test",
  146. Message: nil,
  147. },
  148. result: []map[string]interface{}{{
  149. "a": float64(2),
  150. }},
  151. },
  152. {
  153. sql: "SELECT cos(0) AS a FROM test",
  154. data: &xsql.Tuple{
  155. Emitter: "test",
  156. Message: nil,
  157. },
  158. result: []map[string]interface{}{{
  159. "a": float64(1),
  160. }},
  161. },
  162. {
  163. sql: "SELECT cosh(0) AS a FROM test",
  164. data: &xsql.Tuple{
  165. Emitter: "test",
  166. Message: nil,
  167. },
  168. result: []map[string]interface{}{{
  169. "a": float64(1),
  170. }},
  171. },
  172. {
  173. sql: "SELECT exp(1.2) AS a FROM test",
  174. data: &xsql.Tuple{
  175. Emitter: "test",
  176. Message: nil,
  177. },
  178. result: []map[string]interface{}{{
  179. "a": float64(3.3201169227365472),
  180. }},
  181. },
  182. {
  183. sql: "SELECT ln(1) AS a FROM test",
  184. data: &xsql.Tuple{
  185. Emitter: "test",
  186. Message: nil,
  187. },
  188. result: []map[string]interface{}{{
  189. "a": float64(0),
  190. }},
  191. },
  192. {
  193. sql: "SELECT log(10) AS a FROM test",
  194. data: &xsql.Tuple{
  195. Emitter: "test",
  196. Message: nil,
  197. },
  198. result: []map[string]interface{}{{
  199. "a": float64(1),
  200. }},
  201. },
  202. {
  203. sql: "SELECT mod(10, 3) AS a FROM test",
  204. data: &xsql.Tuple{
  205. Emitter: "test",
  206. Message: nil,
  207. },
  208. result: []map[string]interface{}{{
  209. "a": float64(1),
  210. }},
  211. },
  212. {
  213. sql: "SELECT power(10, 3) AS a FROM test",
  214. data: &xsql.Tuple{
  215. Emitter: "test",
  216. Message: nil,
  217. },
  218. result: []map[string]interface{}{{
  219. "a": float64(1000),
  220. }},
  221. },
  222. {
  223. sql: "SELECT round(10.2) AS a FROM test",
  224. data: &xsql.Tuple{
  225. Emitter: "test",
  226. Message: nil,
  227. },
  228. result: []map[string]interface{}{{
  229. "a": float64(10),
  230. }},
  231. },
  232. {
  233. sql: "SELECT sign(10.2) AS a, sign(-2) as b, sign(0) as c FROM test",
  234. data: &xsql.Tuple{
  235. Emitter: "test",
  236. Message: nil,
  237. },
  238. result: []map[string]interface{}{{
  239. "a": float64(1),
  240. "b": float64(-1),
  241. "c": float64(0),
  242. }},
  243. },
  244. {
  245. sql: "SELECT sin(0) as a FROM test",
  246. data: &xsql.Tuple{
  247. Emitter: "test",
  248. Message: nil,
  249. },
  250. result: []map[string]interface{}{{
  251. "a": float64(0),
  252. }},
  253. },
  254. {
  255. sql: "SELECT sinh(0) as a FROM test",
  256. data: &xsql.Tuple{
  257. Emitter: "test",
  258. Message: nil,
  259. },
  260. result: []map[string]interface{}{{
  261. "a": float64(0),
  262. }},
  263. },
  264. {
  265. sql: "SELECT sqrt(4) as a FROM test",
  266. data: &xsql.Tuple{
  267. Emitter: "test",
  268. Message: nil,
  269. },
  270. result: []map[string]interface{}{{
  271. "a": float64(2),
  272. }},
  273. },
  274. {
  275. sql: "SELECT tan(0) as a FROM test",
  276. data: &xsql.Tuple{
  277. Emitter: "test",
  278. Message: nil,
  279. },
  280. result: []map[string]interface{}{{
  281. "a": float64(0),
  282. }},
  283. },
  284. {
  285. sql: "SELECT tanh(1) as a FROM test",
  286. data: &xsql.Tuple{
  287. Emitter: "test",
  288. Message: nil,
  289. },
  290. result: []map[string]interface{}{{
  291. "a": float64(0.7615941559557649),
  292. }},
  293. },
  294. {
  295. sql: `SELECT cast(1.2, "bigint") as a FROM test`,
  296. data: &xsql.Tuple{
  297. Emitter: "test",
  298. Message: nil,
  299. },
  300. result: []map[string]interface{}{{
  301. "a": float64(1),
  302. }},
  303. },
  304. {
  305. sql: `SELECT cast(5, "bigint") as a FROM test`,
  306. data: &xsql.Tuple{
  307. Emitter: "test",
  308. Message: nil,
  309. },
  310. result: []map[string]interface{}{{
  311. "a": float64(5),
  312. }},
  313. },
  314. {
  315. sql: `SELECT cast(1.2, "string") as a FROM test`,
  316. data: &xsql.Tuple{
  317. Emitter: "test",
  318. Message: nil,
  319. },
  320. result: []map[string]interface{}{{
  321. "a": "1.2",
  322. }},
  323. },
  324. {
  325. sql: `SELECT cast(true, "string") as a FROM test`,
  326. data: &xsql.Tuple{
  327. Emitter: "test",
  328. Message: nil,
  329. },
  330. result: []map[string]interface{}{{
  331. "a": "true",
  332. }},
  333. },
  334. {
  335. sql: `SELECT cast("true", "boolean") as a FROM test`,
  336. data: &xsql.Tuple{
  337. Emitter: "test",
  338. Message: nil,
  339. },
  340. result: []map[string]interface{}{{
  341. "a": true,
  342. }},
  343. },
  344. {
  345. sql: `SELECT cast("1", "boolean") as a FROM test`,
  346. data: &xsql.Tuple{
  347. Emitter: "test",
  348. Message: nil,
  349. },
  350. result: []map[string]interface{}{{
  351. "a": true,
  352. }},
  353. },
  354. {
  355. sql: `SELECT cast(0.0, "boolean") as a FROM test`,
  356. data: &xsql.Tuple{
  357. Emitter: "test",
  358. Message: nil,
  359. },
  360. result: []map[string]interface{}{{
  361. "a": false,
  362. }},
  363. },
  364. {
  365. sql: `SELECT chr(0) as a FROM test`,
  366. data: &xsql.Tuple{
  367. Emitter: "test",
  368. Message: nil,
  369. },
  370. result: []map[string]interface{}{{
  371. "a": float64(0),
  372. }},
  373. },
  374. {
  375. sql: `SELECT chr("a") as a FROM test`,
  376. data: &xsql.Tuple{
  377. Emitter: "test",
  378. Message: nil,
  379. },
  380. result: []map[string]interface{}{{
  381. "a": float64(97),
  382. }},
  383. },
  384. {
  385. sql: `SELECT encode("hello", "base64") as a FROM test`,
  386. data: &xsql.Tuple{
  387. Emitter: "test",
  388. Message: nil,
  389. },
  390. result: []map[string]interface{}{{
  391. "a": "aGVsbG8=",
  392. }},
  393. },
  394. {
  395. sql: `SELECT trunc(3.1415, 2) as a FROM test`,
  396. data: &xsql.Tuple{
  397. Emitter: "test",
  398. Message: nil,
  399. },
  400. result: []map[string]interface{}{{
  401. "a": float64(3.14),
  402. }},
  403. },
  404. {
  405. sql: `SELECT trunc(3, 2) as a FROM test`,
  406. data: &xsql.Tuple{
  407. Emitter: "test",
  408. Message: nil,
  409. },
  410. result: []map[string]interface{}{{
  411. "a": float64(3.00),
  412. }},
  413. },
  414. }
  415. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  416. contextLogger := common.Log.WithField("rule", "TestMathAndConversionFunc_Apply1")
  417. ctx := contexts.WithValue(contexts.Background(), contexts.LoggerKey, contextLogger)
  418. for i, tt := range tests {
  419. //fmt.Println("Running test " + strconv.Itoa(i))
  420. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  421. if err != nil && tt.result == nil {
  422. continue
  423. } else if err != nil && tt.result != nil {
  424. t.Errorf("%q", err)
  425. continue
  426. }
  427. pp := &ProjectPlan{Fields: stmt.Fields}
  428. pp.isTest = true
  429. fv, afv := xsql.NewAggregateFunctionValuers()
  430. result := pp.Apply(ctx, tt.data, fv, afv)
  431. var mapRes []map[string]interface{}
  432. if v, ok := result.([]byte); ok {
  433. err := json.Unmarshal(v, &mapRes)
  434. if err != nil {
  435. t.Errorf("Failed to parse the input into map.\n")
  436. continue
  437. }
  438. //fmt.Printf("%t\n", mapRes["rengine_field_0"])
  439. if !reflect.DeepEqual(tt.result, mapRes) {
  440. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, mapRes)
  441. }
  442. } else {
  443. t.Errorf("The returned result is not type of []byte\n")
  444. }
  445. }
  446. }