join_test.go 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531
  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. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  540. for i, tt := range tests {
  541. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  542. if err != nil {
  543. t.Errorf("statement parse error %s", err)
  544. break
  545. }
  546. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  547. t.Errorf("statement source is not a table")
  548. }else{
  549. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  550. result := pp.Apply(nil, tt.data)
  551. if !reflect.DeepEqual(tt.result, result) {
  552. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  553. }
  554. }
  555. }
  556. }
  557. func TestInnerJoinPlan_Apply(t *testing.T) {
  558. var tests = []struct {
  559. sql string
  560. data xsql.WindowTuplesSet
  561. result interface{}
  562. }{
  563. {
  564. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  565. data: xsql.WindowTuplesSet{
  566. xsql.WindowTuples{
  567. Emitter:"src1",
  568. Tuples:[]xsql.Tuple{
  569. {
  570. Emitter: "src1",
  571. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  572. },{
  573. Emitter: "src1",
  574. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  575. },{
  576. Emitter: "src1",
  577. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  578. },
  579. },
  580. },
  581. xsql.WindowTuples{
  582. Emitter:"src2",
  583. Tuples:[]xsql.Tuple{
  584. {
  585. Emitter: "src2",
  586. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  587. },{
  588. Emitter: "src2",
  589. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  590. },{
  591. Emitter: "src2",
  592. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  593. },
  594. },
  595. },
  596. },
  597. result: xsql.JoinTupleSets{
  598. xsql.JoinTuple{
  599. Tuples: []xsql.Tuple{
  600. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  601. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  602. },
  603. },
  604. xsql.JoinTuple{
  605. Tuples: []xsql.Tuple{
  606. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  607. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  608. },
  609. },
  610. },
  611. },
  612. {
  613. sql: "SELECT id1 FROM src1 As s1 inner join src2 as s2 on s1.id1 = s2.id2",
  614. data: xsql.WindowTuplesSet{
  615. xsql.WindowTuples{
  616. Emitter:"s1",
  617. Tuples:[]xsql.Tuple{
  618. {
  619. Emitter: "s1",
  620. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  621. },{
  622. Emitter: "s1",
  623. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  624. },{
  625. Emitter: "s1",
  626. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  627. },
  628. },
  629. },
  630. xsql.WindowTuples{
  631. Emitter:"s2",
  632. Tuples:[]xsql.Tuple{
  633. {
  634. Emitter: "s2",
  635. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  636. },{
  637. Emitter: "s2",
  638. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  639. },{
  640. Emitter: "s2",
  641. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  642. },
  643. },
  644. },
  645. },
  646. result: xsql.JoinTupleSets{
  647. xsql.JoinTuple{
  648. Tuples: []xsql.Tuple{
  649. {Emitter: "s1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  650. {Emitter: "s2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  651. },
  652. },
  653. xsql.JoinTuple{
  654. Tuples: []xsql.Tuple{
  655. {Emitter: "s1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  656. {Emitter: "s2", Message: xsql.Message{ "id2" : 2, "f2" : "w2"},},
  657. },
  658. },
  659. },
  660. },
  661. {
  662. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  663. data: xsql.WindowTuplesSet{
  664. xsql.WindowTuples{
  665. Emitter:"src1",
  666. Tuples:[]xsql.Tuple{
  667. {
  668. Emitter: "src1",
  669. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  670. },
  671. },
  672. },
  673. xsql.WindowTuples{
  674. Emitter:"src2",
  675. Tuples:[]xsql.Tuple{
  676. {
  677. Emitter: "src2",
  678. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  679. },{
  680. Emitter: "src2",
  681. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  682. },
  683. },
  684. },
  685. },
  686. result: xsql.JoinTupleSets{
  687. xsql.JoinTuple{
  688. Tuples: []xsql.Tuple{
  689. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1"},},
  690. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1"},},
  691. },
  692. },
  693. xsql.JoinTuple{
  694. Tuples: []xsql.Tuple{
  695. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1"},},
  696. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w2"},},
  697. },
  698. },
  699. },
  700. },
  701. {
  702. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  703. data: xsql.WindowTuplesSet{
  704. xsql.WindowTuples{
  705. Emitter:"src1",
  706. Tuples:[]xsql.Tuple{
  707. {
  708. Emitter: "src1",
  709. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  710. },{
  711. Emitter: "src1",
  712. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  713. },{
  714. Emitter: "src1",
  715. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  716. },
  717. },
  718. },
  719. xsql.WindowTuples{
  720. Emitter:"src2",
  721. Tuples:[]xsql.Tuple{
  722. },
  723. },
  724. },
  725. result: nil,
  726. },
  727. {
  728. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  729. data: xsql.WindowTuplesSet{
  730. xsql.WindowTuples{
  731. Emitter:"src1",
  732. Tuples:[]xsql.Tuple{
  733. {
  734. Emitter: "src1",
  735. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  736. },{
  737. Emitter: "src1",
  738. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  739. },{
  740. Emitter: "src1",
  741. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  742. },
  743. },
  744. },
  745. xsql.WindowTuples{
  746. Emitter: "src2",
  747. Tuples: nil,
  748. },
  749. },
  750. result: nil,
  751. },
  752. {
  753. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  754. data: xsql.WindowTuplesSet{
  755. xsql.WindowTuples{
  756. Emitter:"src1",
  757. Tuples:[]xsql.Tuple{},
  758. },
  759. xsql.WindowTuples{
  760. Emitter:"src2",
  761. Tuples:[]xsql.Tuple{
  762. {
  763. Emitter: "src2",
  764. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  765. },{
  766. Emitter: "src2",
  767. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  768. },
  769. },
  770. },
  771. },
  772. result: nil,
  773. },
  774. {
  775. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2",
  776. data: xsql.WindowTuplesSet{
  777. xsql.WindowTuples{
  778. Emitter:"src1",
  779. Tuples:nil,
  780. },
  781. xsql.WindowTuples{
  782. Emitter:"src2",
  783. Tuples:[]xsql.Tuple{
  784. {
  785. Emitter: "src2",
  786. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  787. },{
  788. Emitter: "src2",
  789. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  790. },
  791. },
  792. },
  793. },
  794. result: nil,
  795. },
  796. {
  797. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1*2 = src2.id2",
  798. data: xsql.WindowTuplesSet{
  799. xsql.WindowTuples{
  800. Emitter:"src1",
  801. Tuples:[]xsql.Tuple{
  802. {
  803. Emitter: "src1",
  804. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  805. },{
  806. Emitter: "src1",
  807. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  808. },{
  809. Emitter: "src1",
  810. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  811. },
  812. },
  813. },
  814. xsql.WindowTuples{
  815. Emitter:"src2",
  816. Tuples:[]xsql.Tuple{
  817. {
  818. Emitter: "src2",
  819. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  820. },{
  821. Emitter: "src2",
  822. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  823. },{
  824. Emitter: "src2",
  825. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  826. },
  827. },
  828. },
  829. },
  830. result: xsql.JoinTupleSets{
  831. xsql.JoinTuple{
  832. Tuples: []xsql.Tuple{
  833. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1"}},
  834. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2"}},
  835. },
  836. },
  837. xsql.JoinTuple{
  838. Tuples: []xsql.Tuple{
  839. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2"}},
  840. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3"}},
  841. },
  842. },
  843. },
  844. },
  845. {
  846. sql: "SELECT id1 FROM src1 inner join src2 on src1.id1 = src2.id2*2",
  847. data: xsql.WindowTuplesSet{
  848. xsql.WindowTuples{
  849. Emitter:"src1",
  850. Tuples:[]xsql.Tuple{
  851. {
  852. Emitter: "src1",
  853. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  854. },{
  855. Emitter: "src1",
  856. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  857. },{
  858. Emitter: "src1",
  859. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  860. },
  861. },
  862. },
  863. xsql.WindowTuples{
  864. Emitter:"src2",
  865. Tuples:[]xsql.Tuple{
  866. {
  867. Emitter: "src2",
  868. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  869. },{
  870. Emitter: "src2",
  871. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  872. },{
  873. Emitter: "src2",
  874. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  875. },
  876. },
  877. },
  878. },
  879. result: xsql.JoinTupleSets{
  880. xsql.JoinTuple{
  881. Tuples: []xsql.Tuple{
  882. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  883. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  884. },
  885. },
  886. },
  887. },
  888. {
  889. sql: "SELECT id1 FROM src1 inner join src2 on src1.f1->cid = src2.f2->cid",
  890. data: xsql.WindowTuplesSet{
  891. xsql.WindowTuples{
  892. Emitter:"src1",
  893. Tuples:[]xsql.Tuple{
  894. {
  895. Emitter: "src1",
  896. Message: xsql.Message{ "id1" : 1, "f1" : str2Map(`{"cid" : 1, "name" : "tom1"}`) },
  897. },{
  898. Emitter: "src1",
  899. Message: xsql.Message{ "id1" : 2, "f1" : str2Map(`{"cid" : 2, "name" : "mike1"}`) },
  900. },{
  901. Emitter: "src1",
  902. Message: xsql.Message{ "id1" : 3, "f1" : str2Map(`{"cid" : 3, "name" : "alice1"}`) },
  903. },
  904. },
  905. },
  906. xsql.WindowTuples{
  907. Emitter:"src2",
  908. Tuples:[]xsql.Tuple{
  909. {
  910. Emitter: "src2",
  911. Message: xsql.Message{ "id2" : 1, "f2" : str2Map(`{"cid" : 1, "name" : "tom2"}`)},
  912. },{
  913. Emitter: "src2",
  914. Message: xsql.Message{ "id2" : 2, "f2" : str2Map(`{"cid" : 2, "name" : "mike2"}`) },
  915. },{
  916. Emitter: "src2",
  917. Message: xsql.Message{ "id2" : 4, "f2" : str2Map(`{"cid" : 4, "name" : "alice2"}`) },
  918. },
  919. },
  920. },
  921. },
  922. result: xsql.JoinTupleSets{
  923. xsql.JoinTuple{
  924. Tuples: []xsql.Tuple{
  925. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : str2Map(`{"cid" : 1, "name" : "tom1"}`) },},
  926. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : str2Map(`{"cid" : 1, "name" : "tom2"}`) },},
  927. },
  928. },
  929. xsql.JoinTuple{
  930. Tuples: []xsql.Tuple{
  931. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : str2Map(`{"cid" : 2, "name" : "mike1"}`) },},
  932. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : str2Map(`{"cid" : 2, "name" : "mike2"}`) },},
  933. },
  934. },
  935. },
  936. },
  937. }
  938. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  939. for i, tt := range tests {
  940. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  941. if err != nil {
  942. t.Errorf("statement parse error %s", err)
  943. break
  944. }
  945. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  946. t.Errorf("statement source is not a table")
  947. }else{
  948. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  949. result := pp.Apply(nil, tt.data)
  950. if !reflect.DeepEqual(tt.result, result) {
  951. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  952. }
  953. }
  954. }
  955. }
  956. func TestRightJoinPlan_Apply(t *testing.T) {
  957. var tests = []struct {
  958. sql string
  959. data xsql.WindowTuplesSet
  960. result interface{}
  961. }{
  962. {
  963. sql: "SELECT id1 FROM src1 right join src2 on src1.id1 = src2.id2",
  964. data: xsql.WindowTuplesSet{
  965. xsql.WindowTuples{
  966. Emitter: "src1",
  967. Tuples:[]xsql.Tuple{
  968. {
  969. Emitter: "src1",
  970. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  971. },{
  972. Emitter: "src1",
  973. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  974. },{
  975. Emitter: "src1",
  976. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  977. },
  978. },
  979. },
  980. xsql.WindowTuples{
  981. Emitter: "src2",
  982. Tuples:[]xsql.Tuple{
  983. {
  984. Emitter: "src2",
  985. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  986. },{
  987. Emitter: "src2",
  988. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  989. },{
  990. Emitter: "src2",
  991. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  992. },
  993. },
  994. },
  995. },
  996. result: xsql.JoinTupleSets{
  997. xsql.JoinTuple{
  998. Tuples: []xsql.Tuple{
  999. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1000. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1001. },
  1002. },
  1003. xsql.JoinTuple{
  1004. Tuples: []xsql.Tuple{
  1005. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1006. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1007. },
  1008. },
  1009. xsql.JoinTuple{
  1010. Tuples: []xsql.Tuple{
  1011. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1012. },
  1013. },
  1014. },
  1015. },
  1016. {
  1017. sql: "SELECT id1 FROM src1 right join src2 on src1.id1 = src2.id2",
  1018. data: xsql.WindowTuplesSet{
  1019. xsql.WindowTuples{
  1020. Emitter:"src1",
  1021. Tuples:[]xsql.Tuple{
  1022. {
  1023. Emitter: "src1",
  1024. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1025. },
  1026. },
  1027. },
  1028. xsql.WindowTuples{
  1029. Emitter:"src2",
  1030. Tuples:[]xsql.Tuple{
  1031. {
  1032. Emitter: "src2",
  1033. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1034. },{
  1035. Emitter: "src2",
  1036. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  1037. },
  1038. },
  1039. },
  1040. },
  1041. result: xsql.JoinTupleSets{
  1042. xsql.JoinTuple{
  1043. Tuples: []xsql.Tuple{
  1044. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1045. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1046. },
  1047. },
  1048. xsql.JoinTuple{
  1049. Tuples: []xsql.Tuple{
  1050. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w2" },},
  1051. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1052. },
  1053. },
  1054. },
  1055. },
  1056. }
  1057. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  1058. for i, tt := range tests {
  1059. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  1060. if err != nil {
  1061. t.Errorf("statement parse error %s", err)
  1062. break
  1063. }
  1064. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  1065. t.Errorf("statement source is not a table")
  1066. }else{
  1067. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  1068. result := pp.Apply(nil, tt.data)
  1069. if !reflect.DeepEqual(tt.result, result) {
  1070. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  1071. }
  1072. }
  1073. }
  1074. }
  1075. func TestFullJoinPlan_Apply(t *testing.T) {
  1076. var tests = []struct {
  1077. sql string
  1078. data xsql.WindowTuplesSet
  1079. result interface{}
  1080. }{
  1081. {
  1082. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1083. data: xsql.WindowTuplesSet{
  1084. xsql.WindowTuples{
  1085. Emitter: "src1",
  1086. Tuples:[]xsql.Tuple{
  1087. {
  1088. Emitter: "src1",
  1089. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1090. },{
  1091. Emitter: "src1",
  1092. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1093. },{
  1094. Emitter: "src1",
  1095. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1096. },
  1097. },
  1098. },
  1099. xsql.WindowTuples{
  1100. Emitter: "src2",
  1101. Tuples:[]xsql.Tuple{
  1102. {
  1103. Emitter: "src2",
  1104. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1105. },{
  1106. Emitter: "src2",
  1107. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1108. },{
  1109. Emitter: "src2",
  1110. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1111. },{
  1112. Emitter: "src2",
  1113. Message: xsql.Message{ "id2" : 2, "f2" : "w4" },
  1114. },
  1115. },
  1116. },
  1117. },
  1118. result: xsql.JoinTupleSets{
  1119. xsql.JoinTuple{
  1120. Tuples: []xsql.Tuple{
  1121. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1122. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1123. },
  1124. },
  1125. xsql.JoinTuple{
  1126. Tuples: []xsql.Tuple{
  1127. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1128. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1129. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w4" },},
  1130. },
  1131. },
  1132. xsql.JoinTuple{
  1133. Tuples: []xsql.Tuple{
  1134. {Emitter: "src1", Message: xsql.Message{ "id1": 3, "f1": "v3" },},
  1135. },
  1136. },
  1137. xsql.JoinTuple{
  1138. Tuples: []xsql.Tuple{
  1139. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1140. },
  1141. },
  1142. },
  1143. },
  1144. {
  1145. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1146. data: xsql.WindowTuplesSet{
  1147. xsql.WindowTuples{
  1148. Emitter: "src1",
  1149. Tuples:[]xsql.Tuple{
  1150. {
  1151. Emitter: "src1",
  1152. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1153. },{
  1154. Emitter: "src1",
  1155. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1156. },{
  1157. Emitter: "src1",
  1158. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1159. },
  1160. },
  1161. },
  1162. xsql.WindowTuples{
  1163. Emitter: "src2",
  1164. Tuples:[]xsql.Tuple{
  1165. {
  1166. Emitter: "src2",
  1167. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1168. },{
  1169. Emitter: "src2",
  1170. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1171. },{
  1172. Emitter: "src2",
  1173. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1174. },
  1175. },
  1176. },
  1177. },
  1178. result: xsql.JoinTupleSets{
  1179. xsql.JoinTuple{
  1180. Tuples: []xsql.Tuple{
  1181. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1182. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1183. },
  1184. },
  1185. xsql.JoinTuple{
  1186. Tuples: []xsql.Tuple{
  1187. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1188. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1189. },
  1190. },
  1191. xsql.JoinTuple{
  1192. Tuples: []xsql.Tuple{
  1193. {Emitter: "src1", Message: xsql.Message{ "id1": 3, "f1": "v3" },},
  1194. },
  1195. },
  1196. xsql.JoinTuple{
  1197. Tuples: []xsql.Tuple{
  1198. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1199. },
  1200. },
  1201. },
  1202. },
  1203. {
  1204. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1205. data: xsql.WindowTuplesSet{
  1206. xsql.WindowTuples{
  1207. Emitter: "src1",
  1208. Tuples:[]xsql.Tuple{
  1209. {
  1210. Emitter: "src1",
  1211. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1212. },{
  1213. Emitter: "src1",
  1214. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1215. },{
  1216. Emitter: "src1",
  1217. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1218. },
  1219. },
  1220. },
  1221. xsql.WindowTuples{
  1222. Emitter: "src2",
  1223. Tuples: []xsql.Tuple{ },
  1224. },
  1225. },
  1226. result: xsql.JoinTupleSets{
  1227. xsql.JoinTuple{
  1228. Tuples: []xsql.Tuple{
  1229. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1230. },
  1231. },
  1232. xsql.JoinTuple{
  1233. Tuples: []xsql.Tuple{
  1234. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1235. },
  1236. },
  1237. xsql.JoinTuple{
  1238. Tuples: []xsql.Tuple{
  1239. {Emitter: "src1", Message: xsql.Message{ "id1": 3, "f1": "v3" },},
  1240. },
  1241. },
  1242. },
  1243. },
  1244. {
  1245. sql: "SELECT id1 FROM src1 full join src2 on src1.id1 = src2.id2",
  1246. data: xsql.WindowTuplesSet{
  1247. xsql.WindowTuples{
  1248. Emitter: "src1",
  1249. Tuples: []xsql.Tuple{
  1250. },
  1251. },
  1252. xsql.WindowTuples{
  1253. Emitter: "src2",
  1254. Tuples:[]xsql.Tuple{
  1255. {
  1256. Emitter: "src2",
  1257. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1258. },{
  1259. Emitter: "src2",
  1260. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1261. },{
  1262. Emitter: "src2",
  1263. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1264. },
  1265. },
  1266. },
  1267. },
  1268. result: xsql.JoinTupleSets{
  1269. xsql.JoinTuple{
  1270. Tuples: []xsql.Tuple{
  1271. {Emitter: "src2", Message: xsql.Message{ "id2": 1, "f2": "w1" },},
  1272. },
  1273. },
  1274. xsql.JoinTuple{
  1275. Tuples: []xsql.Tuple{
  1276. {Emitter: "src2", Message: xsql.Message{ "id2": 2, "f2": "w2" },},
  1277. },
  1278. },
  1279. xsql.JoinTuple{
  1280. Tuples: []xsql.Tuple{
  1281. {Emitter: "src2", Message: xsql.Message{ "id2": 4, "f2": "w3" },},
  1282. },
  1283. },
  1284. },
  1285. },
  1286. }
  1287. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  1288. for i, tt := range tests {
  1289. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  1290. if err != nil {
  1291. t.Errorf("statement parse error %s", err)
  1292. break
  1293. }
  1294. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  1295. t.Errorf("statement source is not a table")
  1296. }else{
  1297. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  1298. result := pp.Apply(nil, tt.data)
  1299. if !reflect.DeepEqual(tt.result, result) {
  1300. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  1301. }
  1302. }
  1303. }
  1304. }
  1305. func TestCrossJoinPlan_Apply(t *testing.T) {
  1306. var tests = []struct {
  1307. sql string
  1308. data xsql.WindowTuplesSet
  1309. result interface{}
  1310. }{
  1311. {
  1312. sql: "SELECT id1 FROM src1 cross join src2",
  1313. data: xsql.WindowTuplesSet{
  1314. xsql.WindowTuples{
  1315. Emitter: "src1",
  1316. Tuples:[]xsql.Tuple{
  1317. {
  1318. Emitter: "src1",
  1319. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1320. },{
  1321. Emitter: "src1",
  1322. Message: xsql.Message{ "id1" : 2, "f1" : "v2", },
  1323. },{
  1324. Emitter: "src1",
  1325. Message: xsql.Message{ "id1" : 3, "f1" : "v3", },
  1326. },
  1327. },
  1328. },
  1329. xsql.WindowTuples{
  1330. Emitter: "src2",
  1331. Tuples:[]xsql.Tuple{
  1332. {
  1333. Emitter: "src2",
  1334. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1335. },{
  1336. Emitter: "src2",
  1337. Message: xsql.Message{ "id2" : 2, "f2" : "w2" },
  1338. },{
  1339. Emitter: "src2",
  1340. Message: xsql.Message{ "id2" : 4, "f2" : "w3" },
  1341. },
  1342. },
  1343. },
  1344. },
  1345. result: xsql.JoinTupleSets{
  1346. xsql.JoinTuple{
  1347. Tuples: []xsql.Tuple{
  1348. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1349. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1350. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1351. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3" },},
  1352. },
  1353. },
  1354. xsql.JoinTuple{
  1355. Tuples: []xsql.Tuple{
  1356. {Emitter: "src1", Message: xsql.Message{ "id1" : 2, "f1" : "v2" },},
  1357. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1358. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1359. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3" },},
  1360. },
  1361. },
  1362. xsql.JoinTuple{
  1363. Tuples: []xsql.Tuple{
  1364. {Emitter: "src1", Message: xsql.Message{ "id1" : 3, "f1" : "v3" },},
  1365. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1366. {Emitter: "src2", Message: xsql.Message{ "id2" : 2, "f2" : "w2" },},
  1367. {Emitter: "src2", Message: xsql.Message{ "id2" : 4, "f2" : "w3" },},
  1368. },
  1369. },
  1370. },
  1371. },
  1372. {
  1373. sql: "SELECT id1 FROM src1 cross join src2",
  1374. data: xsql.WindowTuplesSet{
  1375. xsql.WindowTuples{
  1376. Emitter:"src1",
  1377. Tuples:[]xsql.Tuple{
  1378. {
  1379. Emitter: "src1",
  1380. Message: xsql.Message{ "id1" : 1, "f1" : "v1", },
  1381. },
  1382. },
  1383. },
  1384. xsql.WindowTuples{
  1385. Emitter:"src2",
  1386. Tuples:[]xsql.Tuple{
  1387. {
  1388. Emitter: "src2",
  1389. Message: xsql.Message{ "id2" : 1, "f2" : "w1" },
  1390. },{
  1391. Emitter: "src2",
  1392. Message: xsql.Message{ "id2" : 1, "f2" : "w2" },
  1393. },
  1394. },
  1395. },
  1396. },
  1397. result: xsql.JoinTupleSets{
  1398. xsql.JoinTuple{
  1399. Tuples: []xsql.Tuple{
  1400. {Emitter: "src1", Message: xsql.Message{ "id1" : 1, "f1" : "v1" },},
  1401. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w1" },},
  1402. {Emitter: "src2", Message: xsql.Message{ "id2" : 1, "f2" : "w2" },},
  1403. },
  1404. },
  1405. },
  1406. },
  1407. }
  1408. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  1409. for i, tt := range tests {
  1410. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  1411. if err != nil {
  1412. t.Errorf("statement parse error %s", err)
  1413. break
  1414. }
  1415. if table, ok := stmt.Sources[0].(*xsql.Table); !ok{
  1416. t.Errorf("statement source is not a table")
  1417. }else{
  1418. pp := &JoinPlan{Joins: stmt.Joins, From: table}
  1419. result := pp.Apply(nil, tt.data)
  1420. if !reflect.DeepEqual(tt.result, result) {
  1421. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  1422. }
  1423. }
  1424. }
  1425. }
  1426. func str2Map(s string) map[string]interface{} {
  1427. var input map[string]interface{}
  1428. if err := json.Unmarshal([]byte(s), &input); err != nil {
  1429. fmt.Printf("Failed to parse the JSON data.\n")
  1430. return nil
  1431. }
  1432. return input
  1433. }