math_func_test.go 8.9 KB

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