join_test.go 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564
  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 TestLeftJoinPlan_Apply(t *testing.T) {
  12. var tests = []struct {
  13. sql string
  14. data xsql.WindowTuplesSet
  15. result interface{}
  16. }{
  17. {
  18. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2",
  19. data: xsql.WindowTuplesSet{
  20. xsql.WindowTuples{
  21. Emitter:"src1",
  22. Tuples:[]xsql.Tuple{
  23. {
  24. Emitter: "src1",
  25. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  26. },{
  27. Emitter: "src1",
  28. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  29. },{
  30. Emitter: "src1",
  31. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  32. },
  33. },
  34. },
  35. xsql.WindowTuples{
  36. Emitter:"src2",
  37. Tuples:[]xsql.Tuple{
  38. {
  39. Emitter: "src2",
  40. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  41. },{
  42. Emitter: "src2",
  43. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  44. },{
  45. Emitter: "src2",
  46. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  47. },
  48. },
  49. },
  50. },
  51. result: xsql.JoinTupleSets{
  52. xsql.JoinTuple{
  53. Tuples: []xsql.Tuple{
  54. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  55. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  56. },
  57. },
  58. xsql.JoinTuple{
  59. Tuples: []xsql.Tuple{
  60. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  61. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  62. },
  63. },
  64. xsql.JoinTuple{
  65. Tuples: []xsql.Tuple{
  66. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3" },},
  67. },
  68. },
  69. },
  70. },
  71. {
  72. sql: "SELECT id1 FROM src1 left join src2 on src1.ts = src2.ts",
  73. data: xsql.WindowTuplesSet{
  74. xsql.WindowTuples{
  75. Emitter:"src1",
  76. Tuples:[]xsql.Tuple{
  77. {
  78. Emitter: "src1",
  79. Message: xsql.Message{ "id1" : 1, "f1" : "v1", "ts": common.TimeFromUnixMilli(1568854515000)},
  80. },{
  81. Emitter: "src1",
  82. Message: xsql.Message{ "id1" : 2, "f1" : "v2", "ts": common.TimeFromUnixMilli(1568854525000) },
  83. },{
  84. Emitter: "src1",
  85. Message: xsql.Message{ "id1" : 3, "f1" : "v3", "ts": common.TimeFromUnixMilli(1568854535000) },
  86. },
  87. },
  88. },
  89. xsql.WindowTuples{
  90. Emitter:"src2",
  91. Tuples:[]xsql.Tuple{
  92. {
  93. Emitter: "src2",
  94. Message: xsql.Message{ "id2" : 1, "f2" : "w1", "ts": common.TimeFromUnixMilli(1568854515000) },
  95. },{
  96. Emitter: "src2",
  97. Message: xsql.Message{ "id2" : 2, "f2" : "w2", "ts": common.TimeFromUnixMilli(1568854525000) },
  98. },{
  99. Emitter: "src2",
  100. Message: xsql.Message{ "id2" : 4, "f2" : "w3", "ts": common.TimeFromUnixMilli(1568854545000) },
  101. },
  102. },
  103. },
  104. },
  105. result: xsql.JoinTupleSets{
  106. xsql.JoinTuple{
  107. Tuples: []xsql.Tuple{
  108. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1", "ts": common.TimeFromUnixMilli(1568854515000) },},
  109. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1", "ts": common.TimeFromUnixMilli(1568854515000) },},
  110. },
  111. },
  112. xsql.JoinTuple{
  113. Tuples: []xsql.Tuple{
  114. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2", "ts": common.TimeFromUnixMilli(1568854525000) },},
  115. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2", "ts": common.TimeFromUnixMilli(1568854525000) },},
  116. },
  117. },
  118. xsql.JoinTuple{
  119. Tuples: []xsql.Tuple{
  120. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3", "ts": common.TimeFromUnixMilli(1568854535000) },},
  121. },
  122. },
  123. },
  124. },
  125. {
  126. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  127. data: xsql.WindowTuplesSet{
  128. xsql.WindowTuples{
  129. Emitter:"src1",
  130. Tuples:[]xsql.Tuple{
  131. {
  132. Emitter: "src1",
  133. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  134. },{
  135. Emitter: "src1",
  136. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  137. },{
  138. Emitter: "src1",
  139. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  140. },
  141. },
  142. },
  143. xsql.WindowTuples{
  144. Emitter:"src2",
  145. Tuples:[]xsql.Tuple{
  146. {
  147. Emitter: "src2",
  148. Message: xsql.Message{ "id2" : 4, "f2" : "w1" },
  149. },{
  150. Emitter: "src2",
  151. Message: xsql.Message{ "id2" : 5, "f2" : "w2" },
  152. },{
  153. Emitter: "src2",
  154. Message: xsql.Message{ "id2" : 6, "f2" : "w3" },
  155. },
  156. },
  157. },
  158. },
  159. result: nil,
  160. },
  161. {
  162. sql: "SELECT id1 FROM src1 As s1 left join src2 as s2 on s1.id1 = s2.id2",
  163. data: xsql.WindowTuplesSet{
  164. xsql.WindowTuples{
  165. Emitter:"s1",
  166. Tuples:[]xsql.Tuple{
  167. {
  168. Emitter: "s1",
  169. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  170. },{
  171. Emitter: "s1",
  172. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  173. },{
  174. Emitter: "s1",
  175. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  176. },
  177. },
  178. },
  179. xsql.WindowTuples{
  180. Emitter:"s2",
  181. Tuples:[]xsql.Tuple{
  182. {
  183. Emitter: "s2",
  184. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  185. },{
  186. Emitter: "s2",
  187. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  188. },{
  189. Emitter: "s2",
  190. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  191. },
  192. },
  193. },
  194. },
  195. result: xsql.JoinTupleSets{
  196. xsql.JoinTuple{
  197. Tuples: []xsql.Tuple{
  198. {Emitter: "s1", Message: xsql.Message{ "id1" : 1, "f1" : "v1"},},
  199. {Emitter: "s2", Message: xsql.Message{ "id2" : 1, "f2" : "w1"},},
  200. },
  201. },
  202. xsql.JoinTuple{
  203. Tuples: []xsql.Tuple{
  204. {Emitter: "s1", Message: xsql.Message{ "id1" : 2, "f1" : "v2"},},
  205. {Emitter: "s2", Message: xsql.Message{ "id2" : 2, "f2" : "w2"},},
  206. },
  207. },
  208. xsql.JoinTuple{
  209. Tuples: []xsql.Tuple{
  210. {Emitter: "s1", Message: xsql.Message{ "id1" : 3, "f1" : "v3"},},
  211. },
  212. },
  213. },
  214. },
  215. {
  216. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2",
  217. data: xsql.WindowTuplesSet{
  218. xsql.WindowTuples{
  219. Emitter:"src1",
  220. Tuples:[]xsql.Tuple{
  221. {
  222. Emitter: "src1",
  223. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  224. },
  225. },
  226. },
  227. xsql.WindowTuples{
  228. Emitter:"src2",
  229. Tuples:[]xsql.Tuple{
  230. {
  231. Emitter: "src2",
  232. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  233. },{
  234. Emitter: "src2",
  235. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  236. },
  237. },
  238. },
  239. },
  240. result: xsql.JoinTupleSets{
  241. xsql.JoinTuple{
  242. Tuples: []xsql.Tuple{
  243. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  244. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  245. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w2" },},
  246. },
  247. },
  248. },
  249. },
  250. {
  251. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2",
  252. data: xsql.WindowTuplesSet{
  253. xsql.WindowTuples{
  254. Emitter:"src1",
  255. Tuples:[]xsql.Tuple{
  256. {
  257. Emitter: "src1",
  258. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  259. },{
  260. Emitter: "src1",
  261. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  262. },{
  263. Emitter: "src1",
  264. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  265. },
  266. },
  267. },
  268. xsql.WindowTuples{
  269. Emitter:"src2",
  270. Tuples:[]xsql.Tuple{
  271. },
  272. },
  273. },
  274. result: xsql.JoinTupleSets{
  275. xsql.JoinTuple{
  276. Tuples: []xsql.Tuple{
  277. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  278. },
  279. },
  280. xsql.JoinTuple{
  281. Tuples: []xsql.Tuple{
  282. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  283. },
  284. },
  285. xsql.JoinTuple{
  286. Tuples: []xsql.Tuple{
  287. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3" },},
  288. },
  289. },
  290. },
  291. },
  292. {
  293. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2",
  294. data: xsql.WindowTuplesSet{
  295. xsql.WindowTuples{
  296. Emitter:"src1",
  297. Tuples:[]xsql.Tuple{
  298. {
  299. Emitter: "src1",
  300. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  301. },{
  302. Emitter: "src1",
  303. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  304. },{
  305. Emitter: "src1",
  306. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  307. },
  308. },
  309. },
  310. xsql.WindowTuples{
  311. Emitter: "src2",
  312. Tuples: nil,
  313. },
  314. },
  315. result: xsql.JoinTupleSets{
  316. xsql.JoinTuple{
  317. Tuples: []xsql.Tuple{
  318. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  319. },
  320. },
  321. xsql.JoinTuple{
  322. Tuples: []xsql.Tuple{
  323. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  324. },
  325. },
  326. xsql.JoinTuple{
  327. Tuples: []xsql.Tuple{
  328. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3" },},
  329. },
  330. },
  331. },
  332. },
  333. {
  334. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2",
  335. data: xsql.WindowTuplesSet{
  336. xsql.WindowTuples{
  337. Emitter:"src1",
  338. Tuples:[]xsql.Tuple{},
  339. },
  340. xsql.WindowTuples{
  341. Emitter:"src2",
  342. Tuples:[]xsql.Tuple{
  343. {
  344. Emitter: "src2",
  345. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  346. },{
  347. Emitter: "src2",
  348. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  349. },
  350. },
  351. },
  352. },
  353. result: nil,
  354. },
  355. {
  356. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2",
  357. data: xsql.WindowTuplesSet{
  358. xsql.WindowTuples{
  359. Emitter:"src1",
  360. Tuples:nil,
  361. },
  362. xsql.WindowTuples{
  363. Emitter:"src2",
  364. Tuples:[]xsql.Tuple{
  365. {
  366. Emitter: "src2",
  367. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  368. },{
  369. Emitter: "src2",
  370. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  371. },
  372. },
  373. },
  374. },
  375. result: nil,
  376. },
  377. {
  378. sql: "SELECT id1 FROM src1 left join src2 on src1.id1*2 = src2.id2",
  379. data: xsql.WindowTuplesSet{
  380. xsql.WindowTuples{
  381. Emitter:"src1",
  382. Tuples:[]xsql.Tuple{
  383. {
  384. Emitter: "src1",
  385. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  386. },{
  387. Emitter: "src1",
  388. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  389. },{
  390. Emitter: "src1",
  391. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  392. },
  393. },
  394. },
  395. xsql.WindowTuples{
  396. Emitter:"src2",
  397. Tuples:[]xsql.Tuple{
  398. {
  399. Emitter: "src2",
  400. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  401. },{
  402. Emitter: "src2",
  403. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  404. },{
  405. Emitter: "src2",
  406. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  407. },
  408. },
  409. },
  410. },
  411. result: xsql.JoinTupleSets{
  412. xsql.JoinTuple{
  413. Tuples: []xsql.Tuple{
  414. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  415. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  416. },
  417. },
  418. xsql.JoinTuple{
  419. Tuples: []xsql.Tuple{
  420. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  421. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3" },},
  422. },
  423. },
  424. xsql.JoinTuple{
  425. Tuples: []xsql.Tuple{
  426. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3" },},
  427. },
  428. },
  429. },
  430. },
  431. {
  432. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2*2",
  433. data: xsql.WindowTuplesSet{
  434. xsql.WindowTuples{
  435. Emitter:"src1",
  436. Tuples:[]xsql.Tuple{
  437. {
  438. Emitter: "src1",
  439. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  440. },{
  441. Emitter: "src1",
  442. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  443. },{
  444. Emitter: "src1",
  445. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  446. },
  447. },
  448. },
  449. xsql.WindowTuples{
  450. Emitter:"src2",
  451. Tuples:[]xsql.Tuple{
  452. {
  453. Emitter: "src2",
  454. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  455. },{
  456. Emitter: "src2",
  457. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  458. },{
  459. Emitter: "src2",
  460. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  461. },
  462. },
  463. },
  464. },
  465. result: xsql.JoinTupleSets{
  466. xsql.JoinTuple{
  467. Tuples: []xsql.Tuple{
  468. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  469. },
  470. },
  471. xsql.JoinTuple{
  472. Tuples: []xsql.Tuple{
  473. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  474. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  475. },
  476. },
  477. xsql.JoinTuple{
  478. Tuples: []xsql.Tuple{
  479. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3" },},
  480. },
  481. },
  482. },
  483. },
  484. {
  485. sql: "SELECT id1 FROM src1 left join src2 on src1.f1->cid = src2.f2->cid",
  486. data: xsql.WindowTuplesSet{
  487. xsql.WindowTuples{
  488. Emitter:"src1",
  489. Tuples:[]xsql.Tuple{
  490. {
  491. Emitter: "src1",
  492. Message: xsql.Message{ "id1" : 1, "f1" : str2Map(`{"cid" : 1, "name" : "tom1"}`) },
  493. },{
  494. Emitter: "src1",
  495. Message: xsql.Message{ "id1" : 2, "f1" : str2Map(`{"cid" : 2, "name" : "mike1"}`) },
  496. },{
  497. Emitter: "src1",
  498. Message: xsql.Message{ "id1" : 3, "f1" : str2Map(`{"cid" : 3, "name" : "alice1"}`) },
  499. },
  500. },
  501. },
  502. xsql.WindowTuples{
  503. Emitter:"src2",
  504. Tuples:[]xsql.Tuple{
  505. {
  506. Emitter: "src2",
  507. Message: xsql.Message{ "id2" : 1, "f2" : str2Map(`{"cid" : 1, "name" : "tom2"}`) },
  508. },{
  509. Emitter: "src2",
  510. Message: xsql.Message{ "id2" : 2, "f2" : str2Map(`{"cid" : 2, "name" : "mike2"}`) },
  511. },{
  512. Emitter: "src2",
  513. Message: xsql.Message{ "id2" : 4, "f2" : str2Map(`{"cid" : 4, "name" : "alice2"}`) },
  514. },
  515. },
  516. },
  517. },
  518. result: xsql.JoinTupleSets{
  519. xsql.JoinTuple{
  520. Tuples: []xsql.Tuple{
  521. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : str2Map(`{"cid" : 1, "name" : "tom1"}`) },},
  522. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : str2Map(`{"cid" : 1, "name" : "tom2"}`) },},
  523. },
  524. },
  525. xsql.JoinTuple{
  526. Tuples: []xsql.Tuple{
  527. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : str2Map(`{"cid" : 2, "name" : "mike1"}`) },},
  528. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : str2Map(`{"cid" : 2, "name" : "mike2"}`) },},
  529. },
  530. },
  531. xsql.JoinTuple{
  532. Tuples: []xsql.Tuple{
  533. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : str2Map(`{"cid" : 3, "name" : "alice1"}`) },},
  534. },
  535. },
  536. },
  537. },
  538. {
  539. sql: "SELECT id1, mqtt(src1.topic) AS a, mqtt(src2.topic) as b FROM src1 left join src2 on src1.id1 = src2.id2",
  540. data: xsql.WindowTuplesSet{
  541. xsql.WindowTuples{
  542. Emitter:"src1",
  543. Tuples:[]xsql.Tuple{
  544. {
  545. Emitter: "src1",
  546. Message: xsql.Message{ "id1" : 1, "f1" : "v1", xsql.INTERNAL_MQTT_TOPIC_KEY: "devices/type1/device001"},
  547. },
  548. },
  549. },
  550. xsql.WindowTuples{
  551. Emitter:"src2",
  552. Tuples:[]xsql.Tuple{
  553. {
  554. Emitter: "src2",
  555. Message: xsql.Message{ "id2" : 1, "f2" : "w1", xsql.INTERNAL_MQTT_TOPIC_KEY: "devices/type2/device001" },
  556. },
  557. },
  558. },
  559. },
  560. result: xsql.JoinTupleSets{
  561. xsql.JoinTuple{
  562. Tuples: []xsql.Tuple{
  563. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" , xsql.INTERNAL_MQTT_TOPIC_KEY: "devices/type1/device001"},},
  564. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1", xsql.INTERNAL_MQTT_TOPIC_KEY: "devices/type2/device001" },},
  565. },
  566. },
  567. },
  568. },
  569. }
  570. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  571. for i, tt := range tests {
  572. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  573. if err != nil {
  574. t.Errorf("statement parse error %s", err)
  575. break
  576. }
  577. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  578. t.Errorf("statement source is not a table")
  579. }else{
  580. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  581. result := pp.Apply(nil, tt.data)
  582. if !reflect.DeepEqual(tt.result, result) {
  583. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  584. }
  585. }
  586. }
  587. }
  588. func TestInnerJoinPlan_Apply(t *testing.T) {
  589. var tests = []struct {
  590. sql string
  591. data xsql.WindowTuplesSet
  592. result interface{}
  593. }{
  594. {
  595. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  596. data: xsql.WindowTuplesSet{
  597. xsql.WindowTuples{
  598. Emitter:"src1",
  599. Tuples:[]xsql.Tuple{
  600. {
  601. Emitter: "src1",
  602. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  603. },{
  604. Emitter: "src1",
  605. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  606. },{
  607. Emitter: "src1",
  608. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  609. },
  610. },
  611. },
  612. xsql.WindowTuples{
  613. Emitter:"src2",
  614. Tuples:[]xsql.Tuple{
  615. {
  616. Emitter: "src2",
  617. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  618. },{
  619. Emitter: "src2",
  620. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  621. },{
  622. Emitter: "src2",
  623. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  624. },
  625. },
  626. },
  627. },
  628. result: xsql.JoinTupleSets{
  629. xsql.JoinTuple{
  630. Tuples: []xsql.Tuple{
  631. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  632. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  633. },
  634. },
  635. xsql.JoinTuple{
  636. Tuples: []xsql.Tuple{
  637. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  638. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  639. },
  640. },
  641. },
  642. },
  643. {
  644. sql: "SELECT id1 FROM src1 As s1 inner join src2 as s2 on s1.id1 = s2.id2",
  645. data: xsql.WindowTuplesSet{
  646. xsql.WindowTuples{
  647. Emitter:"s1",
  648. Tuples:[]xsql.Tuple{
  649. {
  650. Emitter: "s1",
  651. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  652. },{
  653. Emitter: "s1",
  654. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  655. },{
  656. Emitter: "s1",
  657. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  658. },
  659. },
  660. },
  661. xsql.WindowTuples{
  662. Emitter:"s2",
  663. Tuples:[]xsql.Tuple{
  664. {
  665. Emitter: "s2",
  666. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  667. },{
  668. Emitter: "s2",
  669. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  670. },{
  671. Emitter: "s2",
  672. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  673. },
  674. },
  675. },
  676. },
  677. result: xsql.JoinTupleSets{
  678. xsql.JoinTuple{
  679. Tuples: []xsql.Tuple{
  680. {Emitter: "s1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  681. {Emitter: "s2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  682. },
  683. },
  684. xsql.JoinTuple{
  685. Tuples: []xsql.Tuple{
  686. {Emitter: "s1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  687. {Emitter: "s2", Message: xsql.Message{ "id2" : 2, "f2" : "w2"},},
  688. },
  689. },
  690. },
  691. },
  692. {
  693. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  694. data: xsql.WindowTuplesSet{
  695. xsql.WindowTuples{
  696. Emitter:"src1",
  697. Tuples:[]xsql.Tuple{
  698. {
  699. Emitter: "src1",
  700. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  701. },
  702. },
  703. },
  704. xsql.WindowTuples{
  705. Emitter:"src2",
  706. Tuples:[]xsql.Tuple{
  707. {
  708. Emitter: "src2",
  709. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  710. },{
  711. Emitter: "src2",
  712. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  713. },
  714. },
  715. },
  716. },
  717. result: xsql.JoinTupleSets{
  718. xsql.JoinTuple{
  719. Tuples: []xsql.Tuple{
  720. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1"},},
  721. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1"},},
  722. },
  723. },
  724. xsql.JoinTuple{
  725. Tuples: []xsql.Tuple{
  726. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1"},},
  727. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w2"},},
  728. },
  729. },
  730. },
  731. },
  732. {
  733. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  734. data: xsql.WindowTuplesSet{
  735. xsql.WindowTuples{
  736. Emitter:"src1",
  737. Tuples:[]xsql.Tuple{
  738. {
  739. Emitter: "src1",
  740. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  741. },{
  742. Emitter: "src1",
  743. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  744. },{
  745. Emitter: "src1",
  746. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  747. },
  748. },
  749. },
  750. xsql.WindowTuples{
  751. Emitter:"src2",
  752. Tuples:[]xsql.Tuple{
  753. },
  754. },
  755. },
  756. result: nil,
  757. },
  758. {
  759. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  760. data: xsql.WindowTuplesSet{
  761. xsql.WindowTuples{
  762. Emitter:"src1",
  763. Tuples:[]xsql.Tuple{
  764. {
  765. Emitter: "src1",
  766. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  767. },{
  768. Emitter: "src1",
  769. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  770. },{
  771. Emitter: "src1",
  772. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  773. },
  774. },
  775. },
  776. xsql.WindowTuples{
  777. Emitter: "src2",
  778. Tuples: nil,
  779. },
  780. },
  781. result: nil,
  782. },
  783. {
  784. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  785. data: xsql.WindowTuplesSet{
  786. xsql.WindowTuples{
  787. Emitter:"src1",
  788. Tuples:[]xsql.Tuple{},
  789. },
  790. xsql.WindowTuples{
  791. Emitter:"src2",
  792. Tuples:[]xsql.Tuple{
  793. {
  794. Emitter: "src2",
  795. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  796. },{
  797. Emitter: "src2",
  798. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  799. },
  800. },
  801. },
  802. },
  803. result: nil,
  804. },
  805. {
  806. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  807. data: xsql.WindowTuplesSet{
  808. xsql.WindowTuples{
  809. Emitter:"src1",
  810. Tuples:nil,
  811. },
  812. xsql.WindowTuples{
  813. Emitter:"src2",
  814. Tuples:[]xsql.Tuple{
  815. {
  816. Emitter: "src2",
  817. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  818. },{
  819. Emitter: "src2",
  820. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  821. },
  822. },
  823. },
  824. },
  825. result: nil,
  826. },
  827. {
  828. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1*2 = src2.id2",
  829. data: xsql.WindowTuplesSet{
  830. xsql.WindowTuples{
  831. Emitter:"src1",
  832. Tuples:[]xsql.Tuple{
  833. {
  834. Emitter: "src1",
  835. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  836. },{
  837. Emitter: "src1",
  838. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  839. },{
  840. Emitter: "src1",
  841. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  842. },
  843. },
  844. },
  845. xsql.WindowTuples{
  846. Emitter:"src2",
  847. Tuples:[]xsql.Tuple{
  848. {
  849. Emitter: "src2",
  850. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  851. },{
  852. Emitter: "src2",
  853. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  854. },{
  855. Emitter: "src2",
  856. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  857. },
  858. },
  859. },
  860. },
  861. result: xsql.JoinTupleSets{
  862. xsql.JoinTuple{
  863. Tuples: []xsql.Tuple{
  864. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1"}},
  865. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2"}},
  866. },
  867. },
  868. xsql.JoinTuple{
  869. Tuples: []xsql.Tuple{
  870. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2"}},
  871. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3"}},
  872. },
  873. },
  874. },
  875. },
  876. {
  877. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2*2",
  878. data: xsql.WindowTuplesSet{
  879. xsql.WindowTuples{
  880. Emitter:"src1",
  881. Tuples:[]xsql.Tuple{
  882. {
  883. Emitter: "src1",
  884. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  885. },{
  886. Emitter: "src1",
  887. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  888. },{
  889. Emitter: "src1",
  890. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  891. },
  892. },
  893. },
  894. xsql.WindowTuples{
  895. Emitter:"src2",
  896. Tuples:[]xsql.Tuple{
  897. {
  898. Emitter: "src2",
  899. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  900. },{
  901. Emitter: "src2",
  902. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  903. },{
  904. Emitter: "src2",
  905. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  906. },
  907. },
  908. },
  909. },
  910. result: xsql.JoinTupleSets{
  911. xsql.JoinTuple{
  912. Tuples: []xsql.Tuple{
  913. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  914. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  915. },
  916. },
  917. },
  918. },
  919. {
  920. sql: "SELECT id1 FROM src1 inner join src2 on src1.f1->cid = src2.f2->cid",
  921. data: xsql.WindowTuplesSet{
  922. xsql.WindowTuples{
  923. Emitter:"src1",
  924. Tuples:[]xsql.Tuple{
  925. {
  926. Emitter: "src1",
  927. Message: xsql.Message{ "id1" : 1, "f1" : str2Map(`{"cid" : 1, "name" : "tom1"}`) },
  928. },{
  929. Emitter: "src1",
  930. Message: xsql.Message{ "id1" : 2, "f1" : str2Map(`{"cid" : 2, "name" : "mike1"}`) },
  931. },{
  932. Emitter: "src1",
  933. Message: xsql.Message{ "id1" : 3, "f1" : str2Map(`{"cid" : 3, "name" : "alice1"}`) },
  934. },
  935. },
  936. },
  937. xsql.WindowTuples{
  938. Emitter:"src2",
  939. Tuples:[]xsql.Tuple{
  940. {
  941. Emitter: "src2",
  942. Message: xsql.Message{ "id2" : 1, "f2" : str2Map(`{"cid" : 1, "name" : "tom2"}`)},
  943. },{
  944. Emitter: "src2",
  945. Message: xsql.Message{ "id2" : 2, "f2" : str2Map(`{"cid" : 2, "name" : "mike2"}`) },
  946. },{
  947. Emitter: "src2",
  948. Message: xsql.Message{ "id2" : 4, "f2" : str2Map(`{"cid" : 4, "name" : "alice2"}`) },
  949. },
  950. },
  951. },
  952. },
  953. result: xsql.JoinTupleSets{
  954. xsql.JoinTuple{
  955. Tuples: []xsql.Tuple{
  956. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : str2Map(`{"cid" : 1, "name" : "tom1"}`) },},
  957. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : str2Map(`{"cid" : 1, "name" : "tom2"}`) },},
  958. },
  959. },
  960. xsql.JoinTuple{
  961. Tuples: []xsql.Tuple{
  962. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : str2Map(`{"cid" : 2, "name" : "mike1"}`) },},
  963. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : str2Map(`{"cid" : 2, "name" : "mike2"}`) },},
  964. },
  965. },
  966. },
  967. },
  968. }
  969. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  970. for i, tt := range tests {
  971. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  972. if err != nil {
  973. t.Errorf("statement parse error %s", err)
  974. break
  975. }
  976. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  977. t.Errorf("statement source is not a table")
  978. }else{
  979. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  980. result := pp.Apply(nil, tt.data)
  981. if !reflect.DeepEqual(tt.result, result) {
  982. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  983. }
  984. }
  985. }
  986. }
  987. func TestRightJoinPlan_Apply(t *testing.T) {
  988. var tests = []struct {
  989. sql string
  990. data xsql.WindowTuplesSet
  991. result interface{}
  992. }{
  993. {
  994. sql: "SELECT id1 FROM src1 right join src2 on src1.id1 = src2.id2",
  995. data: xsql.WindowTuplesSet{
  996. xsql.WindowTuples{
  997. Emitter: "src1",
  998. Tuples:[]xsql.Tuple{
  999. {
  1000. Emitter: "src1",
  1001. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1002. },{
  1003. Emitter: "src1",
  1004. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1005. },{
  1006. Emitter: "src1",
  1007. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1008. },
  1009. },
  1010. },
  1011. xsql.WindowTuples{
  1012. Emitter: "src2",
  1013. Tuples:[]xsql.Tuple{
  1014. {
  1015. Emitter: "src2",
  1016. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1017. },{
  1018. Emitter: "src2",
  1019. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1020. },{
  1021. Emitter: "src2",
  1022. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1023. },
  1024. },
  1025. },
  1026. },
  1027. result: xsql.JoinTupleSets{
  1028. xsql.JoinTuple{
  1029. Tuples: []xsql.Tuple{
  1030. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1031. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1032. },
  1033. },
  1034. xsql.JoinTuple{
  1035. Tuples: []xsql.Tuple{
  1036. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1037. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1038. },
  1039. },
  1040. xsql.JoinTuple{
  1041. Tuples: []xsql.Tuple{
  1042. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1043. },
  1044. },
  1045. },
  1046. },
  1047. {
  1048. sql: "SELECT id1 FROM src1 right join src2 on src1.id1 = src2.id2",
  1049. data: xsql.WindowTuplesSet{
  1050. xsql.WindowTuples{
  1051. Emitter:"src1",
  1052. Tuples:[]xsql.Tuple{
  1053. {
  1054. Emitter: "src1",
  1055. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1056. },
  1057. },
  1058. },
  1059. xsql.WindowTuples{
  1060. Emitter:"src2",
  1061. Tuples:[]xsql.Tuple{
  1062. {
  1063. Emitter: "src2",
  1064. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1065. },{
  1066. Emitter: "src2",
  1067. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  1068. },
  1069. },
  1070. },
  1071. },
  1072. result: xsql.JoinTupleSets{
  1073. xsql.JoinTuple{
  1074. Tuples: []xsql.Tuple{
  1075. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1076. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1077. },
  1078. },
  1079. xsql.JoinTuple{
  1080. Tuples: []xsql.Tuple{
  1081. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w2" },},
  1082. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1083. },
  1084. },
  1085. },
  1086. },
  1087. }
  1088. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  1089. for i, tt := range tests {
  1090. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  1091. if err != nil {
  1092. t.Errorf("statement parse error %s", err)
  1093. break
  1094. }
  1095. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  1096. t.Errorf("statement source is not a table")
  1097. }else{
  1098. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  1099. result := pp.Apply(nil, tt.data)
  1100. if !reflect.DeepEqual(tt.result, result) {
  1101. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  1102. }
  1103. }
  1104. }
  1105. }
  1106. func TestFullJoinPlan_Apply(t *testing.T) {
  1107. var tests = []struct {
  1108. sql string
  1109. data xsql.WindowTuplesSet
  1110. result interface{}
  1111. }{
  1112. {
  1113. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1114. data: xsql.WindowTuplesSet{
  1115. xsql.WindowTuples{
  1116. Emitter: "src1",
  1117. Tuples:[]xsql.Tuple{
  1118. {
  1119. Emitter: "src1",
  1120. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1121. },{
  1122. Emitter: "src1",
  1123. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1124. },{
  1125. Emitter: "src1",
  1126. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1127. },
  1128. },
  1129. },
  1130. xsql.WindowTuples{
  1131. Emitter: "src2",
  1132. Tuples:[]xsql.Tuple{
  1133. {
  1134. Emitter: "src2",
  1135. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1136. },{
  1137. Emitter: "src2",
  1138. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1139. },{
  1140. Emitter: "src2",
  1141. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1142. },{
  1143. Emitter: "src2",
  1144. Message: xsql.Message{ "id2" : 2, "f2" : "w4" },
  1145. },
  1146. },
  1147. },
  1148. },
  1149. result: xsql.JoinTupleSets{
  1150. xsql.JoinTuple{
  1151. Tuples: []xsql.Tuple{
  1152. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1153. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1154. },
  1155. },
  1156. xsql.JoinTuple{
  1157. Tuples: []xsql.Tuple{
  1158. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1159. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1160. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w4" },},
  1161. },
  1162. },
  1163. xsql.JoinTuple{
  1164. Tuples: []xsql.Tuple{
  1165. {Emitter: "src1", Message: xsql.Message{ "id1": 3, "f1": "v3" },},
  1166. },
  1167. },
  1168. xsql.JoinTuple{
  1169. Tuples: []xsql.Tuple{
  1170. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1171. },
  1172. },
  1173. },
  1174. },
  1175. {
  1176. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1177. data: xsql.WindowTuplesSet{
  1178. xsql.WindowTuples{
  1179. Emitter: "src1",
  1180. Tuples:[]xsql.Tuple{
  1181. {
  1182. Emitter: "src1",
  1183. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1184. },{
  1185. Emitter: "src1",
  1186. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1187. },{
  1188. Emitter: "src1",
  1189. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1190. },
  1191. },
  1192. },
  1193. xsql.WindowTuples{
  1194. Emitter: "src2",
  1195. Tuples:[]xsql.Tuple{
  1196. {
  1197. Emitter: "src2",
  1198. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1199. },{
  1200. Emitter: "src2",
  1201. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1202. },{
  1203. Emitter: "src2",
  1204. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1205. },
  1206. },
  1207. },
  1208. },
  1209. result: xsql.JoinTupleSets{
  1210. xsql.JoinTuple{
  1211. Tuples: []xsql.Tuple{
  1212. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1213. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1214. },
  1215. },
  1216. xsql.JoinTuple{
  1217. Tuples: []xsql.Tuple{
  1218. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1219. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1220. },
  1221. },
  1222. xsql.JoinTuple{
  1223. Tuples: []xsql.Tuple{
  1224. {Emitter: "src1", Message: xsql.Message{ "id1": 3, "f1": "v3" },},
  1225. },
  1226. },
  1227. xsql.JoinTuple{
  1228. Tuples: []xsql.Tuple{
  1229. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1230. },
  1231. },
  1232. },
  1233. },
  1234. {
  1235. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1236. data: xsql.WindowTuplesSet{
  1237. xsql.WindowTuples{
  1238. Emitter: "src1",
  1239. Tuples:[]xsql.Tuple{
  1240. {
  1241. Emitter: "src1",
  1242. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1243. },{
  1244. Emitter: "src1",
  1245. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1246. },{
  1247. Emitter: "src1",
  1248. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1249. },
  1250. },
  1251. },
  1252. xsql.WindowTuples{
  1253. Emitter: "src2",
  1254. Tuples: []xsql.Tuple{ },
  1255. },
  1256. },
  1257. result: xsql.JoinTupleSets{
  1258. xsql.JoinTuple{
  1259. Tuples: []xsql.Tuple{
  1260. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1261. },
  1262. },
  1263. xsql.JoinTuple{
  1264. Tuples: []xsql.Tuple{
  1265. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1266. },
  1267. },
  1268. xsql.JoinTuple{
  1269. Tuples: []xsql.Tuple{
  1270. {Emitter: "src1", Message: xsql.Message{ "id1": 3, "f1": "v3" },},
  1271. },
  1272. },
  1273. },
  1274. },
  1275. {
  1276. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1277. data: xsql.WindowTuplesSet{
  1278. xsql.WindowTuples{
  1279. Emitter: "src1",
  1280. Tuples: []xsql.Tuple{
  1281. },
  1282. },
  1283. xsql.WindowTuples{
  1284. Emitter: "src2",
  1285. Tuples:[]xsql.Tuple{
  1286. {
  1287. Emitter: "src2",
  1288. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1289. },{
  1290. Emitter: "src2",
  1291. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1292. },{
  1293. Emitter: "src2",
  1294. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1295. },
  1296. },
  1297. },
  1298. },
  1299. result: xsql.JoinTupleSets{
  1300. xsql.JoinTuple{
  1301. Tuples: []xsql.Tuple{
  1302. {Emitter: "src2", Message: xsql.Message{ "id2": 1, "f2": "w1" },},
  1303. },
  1304. },
  1305. xsql.JoinTuple{
  1306. Tuples: []xsql.Tuple{
  1307. {Emitter: "src2", Message: xsql.Message{ "id2": 2, "f2": "w2" },},
  1308. },
  1309. },
  1310. xsql.JoinTuple{
  1311. Tuples: []xsql.Tuple{
  1312. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1313. },
  1314. },
  1315. },
  1316. },
  1317. }
  1318. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  1319. for i, tt := range tests {
  1320. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  1321. if err != nil {
  1322. t.Errorf("statement parse error %s", err)
  1323. break
  1324. }
  1325. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  1326. t.Errorf("statement source is not a table")
  1327. }else{
  1328. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  1329. result := pp.Apply(nil, tt.data)
  1330. if !reflect.DeepEqual(tt.result, result) {
  1331. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  1332. }
  1333. }
  1334. }
  1335. }
  1336. func TestCrossJoinPlan_Apply(t *testing.T) {
  1337. var tests = []struct {
  1338. sql string
  1339. data xsql.WindowTuplesSet
  1340. result interface{}
  1341. }{
  1342. {
  1343. sql: "SELECT id1 FROM src1 cross join src2",
  1344. data: xsql.WindowTuplesSet{
  1345. xsql.WindowTuples{
  1346. Emitter: "src1",
  1347. Tuples:[]xsql.Tuple{
  1348. {
  1349. Emitter: "src1",
  1350. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1351. },{
  1352. Emitter: "src1",
  1353. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1354. },{
  1355. Emitter: "src1",
  1356. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1357. },
  1358. },
  1359. },
  1360. xsql.WindowTuples{
  1361. Emitter: "src2",
  1362. Tuples:[]xsql.Tuple{
  1363. {
  1364. Emitter: "src2",
  1365. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1366. },{
  1367. Emitter: "src2",
  1368. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1369. },{
  1370. Emitter: "src2",
  1371. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1372. },
  1373. },
  1374. },
  1375. },
  1376. result: xsql.JoinTupleSets{
  1377. xsql.JoinTuple{
  1378. Tuples: []xsql.Tuple{
  1379. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1380. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1381. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1382. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3" },},
  1383. },
  1384. },
  1385. xsql.JoinTuple{
  1386. Tuples: []xsql.Tuple{
  1387. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1388. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1389. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1390. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3" },},
  1391. },
  1392. },
  1393. xsql.JoinTuple{
  1394. Tuples: []xsql.Tuple{
  1395. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3" },},
  1396. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1397. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1398. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3" },},
  1399. },
  1400. },
  1401. },
  1402. },
  1403. {
  1404. sql: "SELECT id1 FROM src1 cross join src2",
  1405. data: xsql.WindowTuplesSet{
  1406. xsql.WindowTuples{
  1407. Emitter:"src1",
  1408. Tuples:[]xsql.Tuple{
  1409. {
  1410. Emitter: "src1",
  1411. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1412. },
  1413. },
  1414. },
  1415. xsql.WindowTuples{
  1416. Emitter:"src2",
  1417. Tuples:[]xsql.Tuple{
  1418. {
  1419. Emitter: "src2",
  1420. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1421. },{
  1422. Emitter: "src2",
  1423. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  1424. },
  1425. },
  1426. },
  1427. },
  1428. result: xsql.JoinTupleSets{
  1429. xsql.JoinTuple{
  1430. Tuples: []xsql.Tuple{
  1431. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1432. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1433. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w2" },},
  1434. },
  1435. },
  1436. },
  1437. },
  1438. }
  1439. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  1440. for i, tt := range tests {
  1441. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  1442. if err != nil {
  1443. t.Errorf("statement parse error %s", err)
  1444. break
  1445. }
  1446. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  1447. t.Errorf("statement source is not a table")
  1448. }else{
  1449. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  1450. result := pp.Apply(nil, tt.data)
  1451. if !reflect.DeepEqual(tt.result, result) {
  1452. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  1453. }
  1454. }
  1455. }
  1456. }
  1457. func str2Map(s string) map[string]interface{} {
  1458. var input map[string]interface{}
  1459. if err := json.Unmarshal([]byte(s), &input); err != nil {
  1460. fmt.Printf("Failed to parse the JSON data.\n")
  1461. return nil
  1462. }
  1463. return input
  1464. }