str_func_test.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  355. for i, tt := range tests {
  356. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  357. if err != nil || stmt == nil {
  358. t.Errorf("parse sql %s error %v", tt.sql, err)
  359. }
  360. pp := &ProjectPlan{Fields:stmt.Fields}
  361. result := pp.Apply(nil, tt.data)
  362. var mapRes []map[string]interface{}
  363. if v, ok := result.([]byte); ok {
  364. err := json.Unmarshal(v, &mapRes)
  365. if err != nil {
  366. t.Errorf("Failed to parse the input into map.\n")
  367. continue
  368. }
  369. //fmt.Printf("%t\n", mapRes["rengine_field_0"])
  370. if !reflect.DeepEqual(tt.result, mapRes) {
  371. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, mapRes)
  372. }
  373. } else {
  374. t.Errorf("The returned result is not type of []byte\n")
  375. }
  376. }
  377. }