str_func_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. package plans
  2. import (
  3. "encoding/json"
  4. "engine/common"
  5. "engine/xsql"
  6. "fmt"
  7. "reflect"
  8. "strings"
  9. "testing"
  10. )
  11. func TestStrFunc_Apply1(t *testing.T) {
  12. var tests = []struct {
  13. sql string
  14. data *xsql.Tuple
  15. result []map[string]interface{}
  16. }{
  17. {
  18. sql: "SELECT concat(a, b, c) AS a FROM test",
  19. data: &xsql.Tuple{
  20. Emitter: "test",
  21. Message: xsql.Message{
  22. "a" : "mya",
  23. "b" : "myb",
  24. "c" : "myc",
  25. },
  26. },
  27. result: []map[string]interface{}{{
  28. "a": "myamybmyc",
  29. }},
  30. },
  31. {
  32. sql: "SELECT endswith(a, b) AS a FROM test",
  33. data: &xsql.Tuple{
  34. Emitter: "test",
  35. Message: xsql.Message{
  36. "a" : "mya",
  37. "b" : "myb",
  38. "c" : "myc",
  39. },
  40. },
  41. result: []map[string]interface{}{{
  42. "a": false,
  43. }},
  44. },
  45. {
  46. sql: "SELECT endswith(a, b) AS a FROM test",
  47. data: &xsql.Tuple{
  48. Emitter: "test",
  49. Message: xsql.Message{
  50. "a" : "mya",
  51. "b" : "ya",
  52. "c" : "myc",
  53. },
  54. },
  55. result: []map[string]interface{}{{
  56. "a": true,
  57. }},
  58. },
  59. {
  60. sql: "SELECT format_time(a, \"yyyy-MM-dd T HH:mm:ss\") AS a FROM test",
  61. data: &xsql.Tuple{
  62. Emitter: "test",
  63. Message: xsql.Message{
  64. "a" : common.TimeFromUnixMilli(1568854515000),
  65. "b" : "ya",
  66. "c" : "myc",
  67. },
  68. },
  69. result: []map[string]interface{}{{
  70. "a": "2019-09-19 T 00:55:15",
  71. }},
  72. },
  73. {
  74. sql: "SELECT indexof(a, \"a\") AS a FROM test",
  75. data: &xsql.Tuple{
  76. Emitter: "test",
  77. Message: xsql.Message{
  78. "a" : "mya",
  79. "b" : "ya",
  80. "c" : "myc",
  81. },
  82. },
  83. result: []map[string]interface{}{{
  84. "a": float64(2),
  85. }},
  86. },
  87. {
  88. sql: "SELECT length(a) AS a FROM test",
  89. data: &xsql.Tuple{
  90. Emitter: "test",
  91. Message: xsql.Message{
  92. "a" : "中国",
  93. "b" : "ya",
  94. "c" : "myc",
  95. },
  96. },
  97. result: []map[string]interface{}{{
  98. "a": float64(2),
  99. }},
  100. },
  101. {
  102. sql: "SELECT length(c) AS a FROM test",
  103. data: &xsql.Tuple{
  104. Emitter: "test",
  105. Message: xsql.Message{
  106. "a" : "中国",
  107. "b" : "ya",
  108. "c" : "myc",
  109. },
  110. },
  111. result: []map[string]interface{}{{
  112. "a": float64(3),
  113. }},
  114. },
  115. {
  116. sql: "SELECT lower(a) AS a FROM test",
  117. data: &xsql.Tuple{
  118. Emitter: "test",
  119. Message: xsql.Message{
  120. "a" : "NYCNicks",
  121. "b" : "ya",
  122. "c" : "myc",
  123. },
  124. },
  125. result: []map[string]interface{}{{
  126. "a": "nycnicks",
  127. }},
  128. },
  129. {
  130. sql: "SELECT lpad(a, 2) AS a FROM test",
  131. data: &xsql.Tuple{
  132. Emitter: "test",
  133. Message: xsql.Message{
  134. "a" : "NYCNicks",
  135. "b" : "ya",
  136. "c" : "myc",
  137. },
  138. },
  139. result: []map[string]interface{}{{
  140. "a": " NYCNicks",
  141. }},
  142. },
  143. {
  144. sql: "SELECT ltrim(a) AS a FROM test",
  145. data: &xsql.Tuple{
  146. Emitter: "test",
  147. Message: xsql.Message{
  148. "a" : " \ttrimme\n ",
  149. "b" : "ya",
  150. "c" : "myc",
  151. },
  152. },
  153. result: []map[string]interface{}{{
  154. "a": "trimme\n ",
  155. }},
  156. },
  157. {
  158. sql: "SELECT numbytes(a) AS a FROM test",
  159. data: &xsql.Tuple{
  160. Emitter: "test",
  161. Message: xsql.Message{
  162. "a" : "中国",
  163. "b" : "ya",
  164. "c" : "myc",
  165. },
  166. },
  167. result: []map[string]interface{}{{
  168. "a": float64(6),
  169. }},
  170. },
  171. {
  172. sql: "SELECT numbytes(b) AS a FROM test",
  173. data: &xsql.Tuple{
  174. Emitter: "test",
  175. Message: xsql.Message{
  176. "a" : "中国",
  177. "b" : "ya",
  178. "c" : "myc",
  179. },
  180. },
  181. result: []map[string]interface{}{{
  182. "a": float64(2),
  183. }},
  184. },
  185. {
  186. sql: "SELECT regexp_matches(a,\"foo.*\") AS a FROM test",
  187. data: &xsql.Tuple{
  188. Emitter: "test",
  189. Message: xsql.Message{
  190. "a" : "seafood",
  191. "b" : "ya",
  192. "c" : "myc",
  193. },
  194. },
  195. result: []map[string]interface{}{{
  196. "a": true,
  197. }},
  198. },
  199. {
  200. sql: "SELECT regexp_matches(b,\"foo.*\") AS a FROM test",
  201. data: &xsql.Tuple{
  202. Emitter: "test",
  203. Message: xsql.Message{
  204. "a" : "seafood",
  205. "b" : "ya",
  206. "c" : "myc",
  207. },
  208. },
  209. result: []map[string]interface{}{{
  210. "a": false,
  211. }},
  212. },
  213. {
  214. sql: "SELECT regexp_replace(a,\"a(x*)b\", \"REP\") AS a FROM test",
  215. data: &xsql.Tuple{
  216. Emitter: "test",
  217. Message: xsql.Message{
  218. "a" : "-ab-axxb-",
  219. "b" : "ya",
  220. "c" : "myc",
  221. },
  222. },
  223. result: []map[string]interface{}{{
  224. "a": "-REP-REP-",
  225. }},
  226. },
  227. {
  228. sql: "SELECT regexp_substr(a,\"foo.*\") AS a FROM test",
  229. data: &xsql.Tuple{
  230. Emitter: "test",
  231. Message: xsql.Message{
  232. "a" : "seafood",
  233. "b" : "ya",
  234. "c" : "myc",
  235. },
  236. },
  237. result: []map[string]interface{}{{
  238. "a": "food",
  239. }},
  240. },
  241. {
  242. sql: "SELECT rpad(a, 3) AS a FROM test",
  243. data: &xsql.Tuple{
  244. Emitter: "test",
  245. Message: xsql.Message{
  246. "a" : "NYCNicks",
  247. "b" : "ya",
  248. "c" : "myc",
  249. },
  250. },
  251. result: []map[string]interface{}{{
  252. "a": "NYCNicks ",
  253. }},
  254. },
  255. {
  256. sql: "SELECT rtrim(a) AS a FROM test",
  257. data: &xsql.Tuple{
  258. Emitter: "test",
  259. Message: xsql.Message{
  260. "a" : " \ttrimme\n ",
  261. "b" : "ya",
  262. "c" : "myc",
  263. },
  264. },
  265. result: []map[string]interface{}{{
  266. "a": " \ttrimme",
  267. }},
  268. },
  269. {
  270. sql: "SELECT substring(a, 3) AS a FROM test",
  271. data: &xsql.Tuple{
  272. Emitter: "test",
  273. Message: xsql.Message{
  274. "a" : "NYCNicks",
  275. "b" : "ya",
  276. "c" : "myc",
  277. },
  278. },
  279. result: []map[string]interface{}{{
  280. "a": "Nicks",
  281. }},
  282. },
  283. {
  284. sql: "SELECT substring(a, 3, 5) AS a FROM test",
  285. data: &xsql.Tuple{
  286. Emitter: "test",
  287. Message: xsql.Message{
  288. "a" : "NYCNicks",
  289. "b" : "ya",
  290. "c" : "myc",
  291. },
  292. },
  293. result: []map[string]interface{}{{
  294. "a": "Ni",
  295. }},
  296. },
  297. {
  298. sql: "SELECT endswith(a, b) AS a FROM test",
  299. data: &xsql.Tuple{
  300. Emitter: "test",
  301. Message: xsql.Message{
  302. "a" : "mya",
  303. "b" : "ya",
  304. "c" : "myc",
  305. },
  306. },
  307. result: []map[string]interface{}{{
  308. "a": true,
  309. }},
  310. },
  311. {
  312. sql: "SELECT endswith(a, c) AS a FROM test",
  313. data: &xsql.Tuple{
  314. Emitter: "test",
  315. Message: xsql.Message{
  316. "a" : "mya",
  317. "b" : "ya",
  318. "c" : "myc",
  319. },
  320. },
  321. result: []map[string]interface{}{{
  322. "a": false,
  323. }},
  324. },
  325. {
  326. sql: "SELECT trim(a) AS a FROM test",
  327. data: &xsql.Tuple{
  328. Emitter: "test",
  329. Message: xsql.Message{
  330. "a" : " \ttrimme\n ",
  331. "b" : "ya",
  332. "c" : "myc",
  333. },
  334. },
  335. result: []map[string]interface{}{{
  336. "a": "trimme",
  337. }},
  338. },
  339. {
  340. sql: "SELECT upper(a) AS a FROM test",
  341. data: &xsql.Tuple{
  342. Emitter: "test",
  343. Message: xsql.Message{
  344. "a" : "NYCNicks",
  345. "b" : "ya",
  346. "c" : "myc",
  347. },
  348. },
  349. result: []map[string]interface{}{{
  350. "a": "NYCNICKS",
  351. }},
  352. },
  353. {
  354. sql: `SELECT split_value(a,"/",0) AS a FROM test1`,
  355. data: &xsql.Tuple{
  356. Emitter: "test",
  357. Message: xsql.Message{
  358. "a" : "test/device001/message",
  359. },
  360. },
  361. result: []map[string]interface{}{{
  362. "a": "test",
  363. }},
  364. },
  365. {
  366. sql: `SELECT split_value(a,"/",1) AS a FROM test1`,
  367. data: &xsql.Tuple{
  368. Emitter: "test",
  369. Message: xsql.Message{
  370. "a" : "test/device001/message",
  371. },
  372. },
  373. result: []map[string]interface{}{{
  374. "a": "device001",
  375. }},
  376. },
  377. {
  378. sql: `SELECT split_value(a,"/",2) AS a FROM test1`,
  379. data: &xsql.Tuple{
  380. Emitter: "test",
  381. Message: xsql.Message{
  382. "a" : "test/device001/message",
  383. },
  384. },
  385. result: []map[string]interface{}{{
  386. "a": "message",
  387. }},
  388. },
  389. {
  390. sql: `SELECT split_value(a,"/",0) AS a, split_value(a,"/",3) AS b FROM test1`,
  391. data: &xsql.Tuple{
  392. Emitter: "test",
  393. Message: xsql.Message{
  394. "a" : "/test/device001/message",
  395. },
  396. },
  397. result: []map[string]interface{}{{
  398. "a": "",
  399. "b": "message",
  400. }},
  401. },
  402. {
  403. sql: `SELECT split_value(a,"/",3) AS a FROM test1`,
  404. data: &xsql.Tuple{
  405. Emitter: "test",
  406. Message: xsql.Message{
  407. "a" : "test/device001/message",
  408. },
  409. },
  410. result: []map[string]interface{}{map[string]interface {}{}},
  411. },
  412. }
  413. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  414. for i, tt := range tests {
  415. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  416. if err != nil || stmt == nil {
  417. t.Errorf("parse sql %s error %v", tt.sql, err)
  418. }
  419. pp := &ProjectPlan{Fields:stmt.Fields}
  420. result := pp.Apply(nil, tt.data)
  421. var mapRes []map[string]interface{}
  422. if v, ok := result.([]byte); ok {
  423. err := json.Unmarshal(v, &mapRes)
  424. if err != nil {
  425. t.Errorf("Failed to parse the input into map.\n")
  426. continue
  427. }
  428. //fmt.Printf("%t\n", mapRes["rengine_field_0"])
  429. if !reflect.DeepEqual(tt.result, mapRes) {
  430. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, mapRes)
  431. }
  432. } else {
  433. t.Errorf("The returned result is not type of []byte\n")
  434. }
  435. }
  436. }