join_multi_test.go 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126
  1. // Copyright 2021-2022 EMQ Technologies Co., Ltd.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package operator
  15. import (
  16. "fmt"
  17. "reflect"
  18. "strings"
  19. "testing"
  20. "github.com/lf-edge/ekuiper/internal/conf"
  21. "github.com/lf-edge/ekuiper/internal/topo/context"
  22. "github.com/lf-edge/ekuiper/internal/xsql"
  23. "github.com/lf-edge/ekuiper/pkg/ast"
  24. )
  25. func TestMultiJoinPlan_Apply(t *testing.T) {
  26. tests := []struct {
  27. sql string
  28. data *xsql.WindowTuples
  29. result interface{}
  30. }{
  31. {
  32. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2 left join src3 on src2.id2 = src3.id3",
  33. data: &xsql.WindowTuples{
  34. Content: []xsql.TupleRow{
  35. &xsql.Tuple{
  36. Emitter: "src1",
  37. Message: xsql.Message{"id1": 1, "f1": "v1"},
  38. }, &xsql.Tuple{
  39. Emitter: "src1",
  40. Message: xsql.Message{"id1": 3, "f1": "v3"},
  41. },
  42. &xsql.Tuple{
  43. Emitter: "src2",
  44. Message: xsql.Message{"id2": 1, "f2": "w1"},
  45. }, &xsql.Tuple{
  46. Emitter: "src2",
  47. Message: xsql.Message{"id2": 4, "f2": "w3"},
  48. },
  49. &xsql.Tuple{
  50. Emitter: "src3",
  51. Message: xsql.Message{"id3": 1, "f3": "x1"},
  52. }, &xsql.Tuple{
  53. Emitter: "src3",
  54. Message: xsql.Message{"id3": 5, "f3": "x5"},
  55. },
  56. },
  57. },
  58. result: &xsql.JoinTuples{
  59. Content: []*xsql.JoinTuple{
  60. {
  61. Tuples: []xsql.TupleRow{
  62. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  63. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}},
  64. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 1, "f3": "x1"}},
  65. },
  66. },
  67. {
  68. Tuples: []xsql.TupleRow{
  69. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 3, "f1": "v3"}},
  70. },
  71. },
  72. },
  73. },
  74. },
  75. {
  76. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2 inner join src3 on src2.id2 = src3.id3",
  77. data: &xsql.WindowTuples{
  78. Content: []xsql.TupleRow{
  79. &xsql.Tuple{
  80. Emitter: "src1",
  81. Message: xsql.Message{"id1": 1, "f1": "v1"},
  82. }, &xsql.Tuple{
  83. Emitter: "src1",
  84. Message: xsql.Message{"id1": 3, "f1": "v3"},
  85. },
  86. &xsql.Tuple{
  87. Emitter: "src2",
  88. Message: xsql.Message{"id2": 1, "f2": "w1"},
  89. }, &xsql.Tuple{
  90. Emitter: "src2",
  91. Message: xsql.Message{"id2": 4, "f2": "w3"},
  92. },
  93. &xsql.Tuple{
  94. Emitter: "src3",
  95. Message: xsql.Message{"id3": 1, "f3": "x1"},
  96. }, &xsql.Tuple{
  97. Emitter: "src3",
  98. Message: xsql.Message{"id3": 5, "f3": "x5"},
  99. },
  100. },
  101. WindowRange: xsql.NewWindowRange(1541152486013, 1541152487013),
  102. },
  103. result: &xsql.JoinTuples{
  104. Content: []*xsql.JoinTuple{
  105. {
  106. Tuples: []xsql.TupleRow{
  107. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  108. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}},
  109. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 1, "f3": "x1"}},
  110. },
  111. },
  112. },
  113. WindowRange: xsql.NewWindowRange(1541152486013, 1541152487013),
  114. },
  115. },
  116. {
  117. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2 inner join src3 on src1.id1 = src3.id3",
  118. data: &xsql.WindowTuples{
  119. Content: []xsql.TupleRow{
  120. &xsql.Tuple{
  121. Emitter: "src1",
  122. Message: xsql.Message{"id1": 1, "f1": "v1"},
  123. }, &xsql.Tuple{
  124. Emitter: "src1",
  125. Message: xsql.Message{"id1": 5, "f1": "v5"},
  126. },
  127. &xsql.Tuple{
  128. Emitter: "src2",
  129. Message: xsql.Message{"id2": 1, "f2": "w1"},
  130. }, &xsql.Tuple{
  131. Emitter: "src2",
  132. Message: xsql.Message{"id2": 4, "f2": "w3"},
  133. },
  134. &xsql.Tuple{
  135. Emitter: "src3",
  136. Message: xsql.Message{"id3": 2, "f3": "x1"},
  137. }, &xsql.Tuple{
  138. Emitter: "src3",
  139. Message: xsql.Message{"id3": 5, "f3": "x5"},
  140. },
  141. },
  142. },
  143. result: &xsql.JoinTuples{
  144. Content: []*xsql.JoinTuple{
  145. {
  146. Tuples: []xsql.TupleRow{
  147. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 5, "f1": "v5"}},
  148. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 5, "f3": "x5"}},
  149. },
  150. },
  151. },
  152. },
  153. },
  154. {
  155. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2 full join src3 on src1.id1 = src3.id3",
  156. data: &xsql.WindowTuples{
  157. Content: []xsql.TupleRow{
  158. &xsql.Tuple{
  159. Emitter: "src1",
  160. Message: xsql.Message{"id1": 1, "f1": "v1"},
  161. }, &xsql.Tuple{
  162. Emitter: "src1",
  163. Message: xsql.Message{"id1": 5, "f1": "v5"},
  164. },
  165. &xsql.Tuple{
  166. Emitter: "src2",
  167. Message: xsql.Message{"id2": 1, "f2": "w1"},
  168. }, &xsql.Tuple{
  169. Emitter: "src2",
  170. Message: xsql.Message{"id2": 4, "f2": "w3"},
  171. },
  172. &xsql.Tuple{
  173. Emitter: "src3",
  174. Message: xsql.Message{"id3": 2, "f3": "x1"},
  175. }, &xsql.Tuple{
  176. Emitter: "src3",
  177. Message: xsql.Message{"id3": 5, "f3": "x5"},
  178. },
  179. },
  180. },
  181. result: &xsql.JoinTuples{
  182. Content: []*xsql.JoinTuple{
  183. {
  184. Tuples: []xsql.TupleRow{
  185. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  186. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}},
  187. },
  188. },
  189. {
  190. Tuples: []xsql.TupleRow{
  191. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 5, "f1": "v5"}},
  192. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 5, "f3": "x5"}},
  193. },
  194. },
  195. {
  196. Tuples: []xsql.TupleRow{
  197. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 2, "f3": "x1"}},
  198. },
  199. },
  200. },
  201. },
  202. },
  203. {
  204. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2 right join src3 on src2.id2 = src3.id3",
  205. data: &xsql.WindowTuples{
  206. Content: []xsql.TupleRow{
  207. &xsql.Tuple{
  208. Emitter: "src1",
  209. Message: xsql.Message{"id1": 1, "f1": "v1"},
  210. }, &xsql.Tuple{
  211. Emitter: "src1",
  212. Message: xsql.Message{"id1": 3, "f1": "v3"},
  213. },
  214. &xsql.Tuple{
  215. Emitter: "src2",
  216. Message: xsql.Message{"id2": 1, "f2": "w1"},
  217. }, &xsql.Tuple{
  218. Emitter: "src2",
  219. Message: xsql.Message{"id2": 4, "f2": "w3"},
  220. },
  221. &xsql.Tuple{
  222. Emitter: "src3",
  223. Message: xsql.Message{"id3": 1, "f3": "x1"},
  224. }, &xsql.Tuple{
  225. Emitter: "src3",
  226. Message: xsql.Message{"id3": 5, "f3": "x5"},
  227. },
  228. },
  229. },
  230. result: &xsql.JoinTuples{
  231. Content: []*xsql.JoinTuple{
  232. {
  233. Tuples: []xsql.TupleRow{
  234. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 1, "f3": "x1"}},
  235. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  236. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}},
  237. },
  238. },
  239. {
  240. Tuples: []xsql.TupleRow{
  241. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 5, "f3": "x5"}},
  242. },
  243. },
  244. },
  245. },
  246. },
  247. {
  248. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2 right join src3 on src2.id2 = src3.id3",
  249. data: &xsql.WindowTuples{
  250. Content: []xsql.TupleRow{
  251. &xsql.Tuple{
  252. Emitter: "src1",
  253. Message: xsql.Message{"id1": 1, "f1": "v1"},
  254. }, &xsql.Tuple{
  255. Emitter: "src1",
  256. Message: xsql.Message{"id1": 1, "f1": "v3"},
  257. },
  258. &xsql.Tuple{
  259. Emitter: "src2",
  260. Message: xsql.Message{"id2": 1, "f2": "w1"},
  261. }, &xsql.Tuple{
  262. Emitter: "src2",
  263. Message: xsql.Message{"id2": 1, "f2": "w3"},
  264. },
  265. &xsql.Tuple{
  266. Emitter: "src3",
  267. Message: xsql.Message{"id3": 1, "f3": "x1"},
  268. }, &xsql.Tuple{
  269. Emitter: "src3",
  270. Message: xsql.Message{"id3": 5, "f3": "x5"},
  271. },
  272. },
  273. },
  274. result: &xsql.JoinTuples{
  275. Content: []*xsql.JoinTuple{
  276. {
  277. Tuples: []xsql.TupleRow{
  278. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 1, "f3": "x1"}},
  279. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  280. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}},
  281. },
  282. },
  283. {
  284. Tuples: []xsql.TupleRow{
  285. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 1, "f3": "x1"}},
  286. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  287. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w3"}},
  288. },
  289. },
  290. {
  291. Tuples: []xsql.TupleRow{
  292. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 1, "f3": "x1"}},
  293. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v3"}},
  294. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}},
  295. },
  296. },
  297. {
  298. Tuples: []xsql.TupleRow{
  299. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 1, "f3": "x1"}},
  300. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v3"}},
  301. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w3"}},
  302. },
  303. },
  304. {
  305. Tuples: []xsql.TupleRow{
  306. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 5, "f3": "x5"}},
  307. },
  308. },
  309. },
  310. },
  311. },
  312. {
  313. sql: "SELECT id1 FROM src1 left join src2 on src1.id1 = src2.id2 cross join src3",
  314. data: &xsql.WindowTuples{
  315. Content: []xsql.TupleRow{
  316. &xsql.Tuple{
  317. Emitter: "src1",
  318. Message: xsql.Message{"id1": 1, "f1": "v1"},
  319. }, &xsql.Tuple{
  320. Emitter: "src1",
  321. Message: xsql.Message{"id1": 5, "f1": "v5"},
  322. },
  323. &xsql.Tuple{
  324. Emitter: "src2",
  325. Message: xsql.Message{"id2": 1, "f2": "w1"},
  326. }, &xsql.Tuple{
  327. Emitter: "src2",
  328. Message: xsql.Message{"id2": 4, "f2": "w3"},
  329. },
  330. &xsql.Tuple{
  331. Emitter: "src3",
  332. Message: xsql.Message{"id3": 2, "f3": "x1"},
  333. }, &xsql.Tuple{
  334. Emitter: "src3",
  335. Message: xsql.Message{"id3": 5, "f3": "x5"},
  336. },
  337. },
  338. },
  339. result: &xsql.JoinTuples{
  340. Content: []*xsql.JoinTuple{
  341. {
  342. Tuples: []xsql.TupleRow{
  343. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  344. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}},
  345. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 2, "f3": "x1"}},
  346. },
  347. },
  348. {
  349. Tuples: []xsql.TupleRow{
  350. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 1, "f1": "v1"}},
  351. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id2": 1, "f2": "w1"}}, &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 5, "f3": "x5"}},
  352. },
  353. },
  354. {
  355. Tuples: []xsql.TupleRow{
  356. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 5, "f1": "v5"}},
  357. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 2, "f3": "x1"}},
  358. },
  359. },
  360. {
  361. Tuples: []xsql.TupleRow{
  362. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id1": 5, "f1": "v5"}},
  363. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id3": 5, "f3": "x5"}},
  364. },
  365. },
  366. },
  367. },
  368. },
  369. {
  370. sql: "SELECT id1 FROM src1 inner join src2 on src1.id = src2.id inner join src3 on src1.id = src3.id",
  371. data: &xsql.WindowTuples{
  372. Content: []xsql.TupleRow{
  373. &xsql.Tuple{
  374. Emitter: "src1",
  375. Message: xsql.Message{"id": 1, "f1": "v1"},
  376. }, &xsql.Tuple{
  377. Emitter: "src1",
  378. Message: xsql.Message{"id": 2, "f1": "v5"},
  379. }, &xsql.Tuple{
  380. Emitter: "src1",
  381. Message: xsql.Message{"id": 3, "f1": "v3"},
  382. },
  383. &xsql.Tuple{
  384. Emitter: "src2",
  385. Message: xsql.Message{"id": 1, "f2": "w1"},
  386. }, &xsql.Tuple{
  387. Emitter: "src2",
  388. Message: xsql.Message{"id": 2, "f2": "w2"},
  389. }, &xsql.Tuple{
  390. Emitter: "src2",
  391. Message: xsql.Message{"id": 4, "f2": "w3"},
  392. },
  393. &xsql.Tuple{
  394. Emitter: "src3",
  395. Message: xsql.Message{"id": 1, "f3": "x1"},
  396. }, &xsql.Tuple{
  397. Emitter: "src3",
  398. Message: xsql.Message{"id": 1, "f3": "x3"},
  399. }, &xsql.Tuple{
  400. Emitter: "src3",
  401. Message: xsql.Message{"id": 5, "f3": "x5"},
  402. },
  403. },
  404. },
  405. result: &xsql.JoinTuples{
  406. Content: []*xsql.JoinTuple{
  407. {
  408. Tuples: []xsql.TupleRow{
  409. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  410. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  411. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  412. },
  413. },
  414. {
  415. Tuples: []xsql.TupleRow{
  416. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  417. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  418. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x3"}},
  419. },
  420. },
  421. },
  422. },
  423. },
  424. { // 9
  425. sql: "SELECT id1 FROM src1 inner join src2 on src1.id = src2.id right join src3 on src1.id = src3.id",
  426. data: &xsql.WindowTuples{
  427. Content: []xsql.TupleRow{
  428. &xsql.Tuple{
  429. Emitter: "src1",
  430. Message: xsql.Message{"id": 1, "f1": "v1"},
  431. }, &xsql.Tuple{
  432. Emitter: "src1",
  433. Message: xsql.Message{"id": 2, "f1": "v5"},
  434. }, &xsql.Tuple{
  435. Emitter: "src1",
  436. Message: xsql.Message{"id": 3, "f1": "v3"},
  437. },
  438. &xsql.Tuple{
  439. Emitter: "src2",
  440. Message: xsql.Message{"id": 1, "f2": "w1"},
  441. }, &xsql.Tuple{
  442. Emitter: "src2",
  443. Message: xsql.Message{"id": 2, "f2": "w2"},
  444. }, &xsql.Tuple{
  445. Emitter: "src2",
  446. Message: xsql.Message{"id": 4, "f2": "w3"},
  447. },
  448. &xsql.Tuple{
  449. Emitter: "src3",
  450. Message: xsql.Message{"id": 1, "f3": "x1"},
  451. }, &xsql.Tuple{
  452. Emitter: "src3",
  453. Message: xsql.Message{"id": 1, "f3": "x3"},
  454. }, &xsql.Tuple{
  455. Emitter: "src3",
  456. Message: xsql.Message{"id": 5, "f3": "x5"},
  457. },
  458. },
  459. },
  460. result: &xsql.JoinTuples{
  461. Content: []*xsql.JoinTuple{
  462. {
  463. Tuples: []xsql.TupleRow{
  464. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  465. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  466. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  467. },
  468. },
  469. {
  470. Tuples: []xsql.TupleRow{
  471. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x3"}},
  472. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  473. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  474. },
  475. },
  476. {
  477. Tuples: []xsql.TupleRow{
  478. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 5, "f3": "x5"}},
  479. },
  480. },
  481. },
  482. },
  483. },
  484. { // 10
  485. sql: "SELECT id1 FROM src1 inner join src2 on src1.id * 10 = src2.id right join src3 on src1.id = src3.id",
  486. data: &xsql.WindowTuples{
  487. Content: []xsql.TupleRow{
  488. &xsql.Tuple{
  489. Emitter: "src1",
  490. Message: xsql.Message{"id": 1, "f1": "v1"},
  491. }, &xsql.Tuple{
  492. Emitter: "src1",
  493. Message: xsql.Message{"id": 2, "f1": "v5"},
  494. }, &xsql.Tuple{
  495. Emitter: "src1",
  496. Message: xsql.Message{"id": 3, "f1": "v3"},
  497. },
  498. &xsql.Tuple{
  499. Emitter: "src2",
  500. Message: xsql.Message{"id": 1, "f2": "w1"},
  501. }, &xsql.Tuple{
  502. Emitter: "src2",
  503. Message: xsql.Message{"id": 2, "f2": "w2"},
  504. }, &xsql.Tuple{
  505. Emitter: "src2",
  506. Message: xsql.Message{"id": 4, "f2": "w3"},
  507. },
  508. &xsql.Tuple{
  509. Emitter: "src3",
  510. Message: xsql.Message{"id": 1, "f3": "x1"},
  511. }, &xsql.Tuple{
  512. Emitter: "src3",
  513. Message: xsql.Message{"id": 1, "f3": "x3"},
  514. }, &xsql.Tuple{
  515. Emitter: "src3",
  516. Message: xsql.Message{"id": 5, "f3": "x5"},
  517. },
  518. },
  519. },
  520. result: &xsql.JoinTuples{
  521. Content: []*xsql.JoinTuple{
  522. {
  523. Tuples: []xsql.TupleRow{
  524. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  525. },
  526. },
  527. {
  528. Tuples: []xsql.TupleRow{
  529. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x3"}},
  530. },
  531. },
  532. {
  533. Tuples: []xsql.TupleRow{
  534. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 5, "f3": "x5"}},
  535. },
  536. },
  537. },
  538. },
  539. },
  540. { // 11
  541. sql: "SELECT id1 FROM src1 full join src2 on src1.id = src2.id inner join src3 on src1.id = src3.id",
  542. data: &xsql.WindowTuples{
  543. Content: []xsql.TupleRow{
  544. &xsql.Tuple{
  545. Emitter: "src1",
  546. Message: xsql.Message{"id": 1, "f1": "v1"},
  547. },
  548. &xsql.Tuple{
  549. Emitter: "src1",
  550. Message: xsql.Message{"id": 2, "f1": "v5"},
  551. },
  552. &xsql.Tuple{
  553. Emitter: "src1",
  554. Message: xsql.Message{"id": 3, "f1": "v3"},
  555. },
  556. &xsql.Tuple{
  557. Emitter: "src2",
  558. Message: xsql.Message{"id": 1, "f2": "w1"},
  559. },
  560. &xsql.Tuple{
  561. Emitter: "src2",
  562. Message: xsql.Message{"id": 2, "f2": "w2"},
  563. },
  564. &xsql.Tuple{
  565. Emitter: "src2",
  566. Message: xsql.Message{"id": 4, "f2": "w3"},
  567. },
  568. &xsql.Tuple{
  569. Emitter: "src3",
  570. Message: xsql.Message{"id": 1, "f3": "x1"},
  571. }, &xsql.Tuple{
  572. Emitter: "src3",
  573. Message: xsql.Message{"id": 1, "f3": "x3"},
  574. }, &xsql.Tuple{
  575. Emitter: "src3",
  576. Message: xsql.Message{"id": 5, "f3": "x5"},
  577. },
  578. },
  579. },
  580. result: &xsql.JoinTuples{
  581. Content: []*xsql.JoinTuple{
  582. {
  583. Tuples: []xsql.TupleRow{
  584. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  585. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  586. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  587. },
  588. },
  589. {
  590. Tuples: []xsql.TupleRow{
  591. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  592. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  593. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x3"}},
  594. },
  595. },
  596. },
  597. },
  598. },
  599. { // 12
  600. sql: "SELECT id1 FROM src1 full join src2 on src1.id = src2.id right join src3 on src1.id = src3.id",
  601. data: &xsql.WindowTuples{
  602. Content: []xsql.TupleRow{
  603. &xsql.Tuple{
  604. Emitter: "src1",
  605. Message: xsql.Message{"id": 1, "f1": "v1"},
  606. },
  607. &xsql.Tuple{
  608. Emitter: "src1",
  609. Message: xsql.Message{"id": 2, "f1": "v5"},
  610. },
  611. &xsql.Tuple{
  612. Emitter: "src1",
  613. Message: xsql.Message{"id": 3, "f1": "v3"},
  614. },
  615. &xsql.Tuple{
  616. Emitter: "src2",
  617. Message: xsql.Message{"id": 1, "f2": "w1"},
  618. },
  619. &xsql.Tuple{
  620. Emitter: "src2",
  621. Message: xsql.Message{"id": 2, "f2": "w2"},
  622. },
  623. &xsql.Tuple{
  624. Emitter: "src2",
  625. Message: xsql.Message{"id": 4, "f2": "w3"},
  626. },
  627. &xsql.Tuple{
  628. Emitter: "src3",
  629. Message: xsql.Message{"id": 1, "f3": "x1"},
  630. }, &xsql.Tuple{
  631. Emitter: "src3",
  632. Message: xsql.Message{"id": 1, "f3": "x3"},
  633. }, &xsql.Tuple{
  634. Emitter: "src3",
  635. Message: xsql.Message{"id": 5, "f3": "x5"},
  636. },
  637. },
  638. },
  639. result: &xsql.JoinTuples{
  640. Content: []*xsql.JoinTuple{
  641. {
  642. Tuples: []xsql.TupleRow{
  643. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  644. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  645. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  646. },
  647. },
  648. {
  649. Tuples: []xsql.TupleRow{
  650. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x3"}},
  651. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  652. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  653. },
  654. },
  655. {
  656. Tuples: []xsql.TupleRow{
  657. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 5, "f3": "x5"}},
  658. },
  659. },
  660. },
  661. },
  662. },
  663. { // 13
  664. sql: "SELECT id1 FROM src1 full join src2 on src1.id = src2.id full join src3 on src1.id = src3.id",
  665. data: &xsql.WindowTuples{
  666. Content: []xsql.TupleRow{
  667. &xsql.Tuple{
  668. Emitter: "src1",
  669. Message: xsql.Message{"id": 1, "f1": "v1"},
  670. },
  671. &xsql.Tuple{
  672. Emitter: "src2",
  673. Message: xsql.Message{"id": 2, "f2": "w2"},
  674. },
  675. &xsql.Tuple{
  676. Emitter: "src3",
  677. Message: xsql.Message{"id": 5, "f3": "x5"},
  678. },
  679. },
  680. },
  681. result: &xsql.JoinTuples{
  682. Content: []*xsql.JoinTuple{
  683. {
  684. Tuples: []xsql.TupleRow{
  685. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  686. },
  687. },
  688. {
  689. Tuples: []xsql.TupleRow{
  690. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 2, "f2": "w2"}},
  691. },
  692. },
  693. {
  694. Tuples: []xsql.TupleRow{
  695. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 5, "f3": "x5"}},
  696. },
  697. },
  698. },
  699. },
  700. },
  701. { // 14
  702. sql: "SELECT id1 FROM src1 right join src2 on src1.id = src2.id right join src3 on src1.id = src3.id",
  703. data: &xsql.WindowTuples{
  704. Content: []xsql.TupleRow{
  705. &xsql.Tuple{
  706. Emitter: "src1",
  707. Message: xsql.Message{"id": 1, "f1": "v1"},
  708. },
  709. &xsql.Tuple{
  710. Emitter: "src1",
  711. Message: xsql.Message{"id": 2, "f1": "v5"},
  712. },
  713. &xsql.Tuple{
  714. Emitter: "src1",
  715. Message: xsql.Message{"id": 3, "f1": "v3"},
  716. },
  717. &xsql.Tuple{
  718. Emitter: "src2",
  719. Message: xsql.Message{"id": 1, "f2": "w1"},
  720. },
  721. &xsql.Tuple{
  722. Emitter: "src2",
  723. Message: xsql.Message{"id": 2, "f2": "w2"},
  724. },
  725. &xsql.Tuple{
  726. Emitter: "src2",
  727. Message: xsql.Message{"id": 4, "f2": "w3"},
  728. },
  729. &xsql.Tuple{
  730. Emitter: "src3",
  731. Message: xsql.Message{"id": 1, "f3": "x1"},
  732. }, &xsql.Tuple{
  733. Emitter: "src3",
  734. Message: xsql.Message{"id": 1, "f3": "x3"},
  735. }, &xsql.Tuple{
  736. Emitter: "src3",
  737. Message: xsql.Message{"id": 5, "f3": "x5"},
  738. },
  739. },
  740. },
  741. result: &xsql.JoinTuples{
  742. Content: []*xsql.JoinTuple{
  743. {
  744. Tuples: []xsql.TupleRow{
  745. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  746. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  747. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  748. },
  749. },
  750. {
  751. Tuples: []xsql.TupleRow{
  752. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x3"}},
  753. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  754. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  755. },
  756. },
  757. {
  758. Tuples: []xsql.TupleRow{
  759. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 5, "f3": "x5"}},
  760. },
  761. },
  762. },
  763. },
  764. },
  765. { // 15
  766. sql: "SELECT id1 FROM src1 right join src2 on src1.id = src2.id right join src3 on src1.id = src3.id",
  767. data: &xsql.WindowTuples{
  768. Content: []xsql.TupleRow{
  769. &xsql.Tuple{
  770. Emitter: "src1",
  771. Message: xsql.Message{"id": 1, "f1": "v1"},
  772. },
  773. &xsql.Tuple{
  774. Emitter: "src1",
  775. Message: xsql.Message{"id": 2, "f1": "v5"},
  776. },
  777. &xsql.Tuple{
  778. Emitter: "src1",
  779. Message: xsql.Message{"id": 3, "f1": "v3"},
  780. },
  781. &xsql.Tuple{
  782. Emitter: "src2",
  783. Message: xsql.Message{"id": 1, "f2": "w1"},
  784. },
  785. &xsql.Tuple{
  786. Emitter: "src2",
  787. Message: xsql.Message{"id": 2, "f2": "w2"},
  788. },
  789. &xsql.Tuple{
  790. Emitter: "src2",
  791. Message: xsql.Message{"id": 4, "f2": "w3"},
  792. },
  793. },
  794. },
  795. result: nil,
  796. },
  797. { // 16
  798. sql: "SELECT id1 FROM src1 right join src2 on src1.id = src2.id right join src3 on src1.id = src3.id right join src4 on src4.id = src3.id ",
  799. data: &xsql.WindowTuples{
  800. Content: []xsql.TupleRow{
  801. &xsql.Tuple{
  802. Emitter: "src1",
  803. Message: xsql.Message{"id": 1, "f1": "v1"},
  804. },
  805. &xsql.Tuple{
  806. Emitter: "src1",
  807. Message: xsql.Message{"id": 2, "f1": "v5"},
  808. },
  809. &xsql.Tuple{
  810. Emitter: "src1",
  811. Message: xsql.Message{"id": 3, "f1": "v3"},
  812. },
  813. &xsql.Tuple{
  814. Emitter: "src2",
  815. Message: xsql.Message{"id": 1, "f2": "w1"},
  816. },
  817. &xsql.Tuple{
  818. Emitter: "src2",
  819. Message: xsql.Message{"id": 2, "f2": "w2"},
  820. },
  821. &xsql.Tuple{
  822. Emitter: "src2",
  823. Message: xsql.Message{"id": 4, "f2": "w3"},
  824. },
  825. &xsql.Tuple{
  826. Emitter: "src3",
  827. Message: xsql.Message{"id": 1, "f3": "x1"},
  828. },
  829. &xsql.Tuple{
  830. Emitter: "src3",
  831. Message: xsql.Message{"id": 5, "f3": "x5"},
  832. },
  833. &xsql.Tuple{
  834. Emitter: "src4",
  835. Message: xsql.Message{"id": 1, "f4": "x4"},
  836. },
  837. &xsql.Tuple{
  838. Emitter: "src4",
  839. Message: xsql.Message{"id": 2, "f4": "x4"},
  840. },
  841. },
  842. },
  843. result: &xsql.JoinTuples{
  844. Content: []*xsql.JoinTuple{
  845. {
  846. Tuples: []xsql.TupleRow{
  847. &xsql.Tuple{Emitter: "src4", Message: xsql.Message{"id": 1, "f4": "x4"}},
  848. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  849. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  850. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  851. },
  852. },
  853. {
  854. Tuples: []xsql.TupleRow{
  855. &xsql.Tuple{Emitter: "src4", Message: xsql.Message{"id": 2, "f4": "x4"}},
  856. },
  857. },
  858. },
  859. },
  860. },
  861. { // 17
  862. sql: "SELECT id1 FROM src1 right join src2 on src1.id = src2.id right join src3 on src1.id = src3.id cross join src4",
  863. data: &xsql.WindowTuples{
  864. Content: []xsql.TupleRow{
  865. &xsql.Tuple{
  866. Emitter: "src1",
  867. Message: xsql.Message{"id": 1, "f1": "v1"},
  868. },
  869. &xsql.Tuple{
  870. Emitter: "src1",
  871. Message: xsql.Message{"id": 2, "f1": "v5"},
  872. },
  873. &xsql.Tuple{
  874. Emitter: "src1",
  875. Message: xsql.Message{"id": 3, "f1": "v3"},
  876. },
  877. &xsql.Tuple{
  878. Emitter: "src2",
  879. Message: xsql.Message{"id": 1, "f2": "w1"},
  880. },
  881. &xsql.Tuple{
  882. Emitter: "src2",
  883. Message: xsql.Message{"id": 2, "f2": "w2"},
  884. },
  885. &xsql.Tuple{
  886. Emitter: "src2",
  887. Message: xsql.Message{"id": 4, "f2": "w3"},
  888. },
  889. &xsql.Tuple{
  890. Emitter: "src3",
  891. Message: xsql.Message{"id": 1, "f3": "x1"},
  892. },
  893. &xsql.Tuple{
  894. Emitter: "src3",
  895. Message: xsql.Message{"id": 5, "f3": "x5"},
  896. },
  897. },
  898. },
  899. result: nil,
  900. },
  901. { // 18
  902. sql: "SELECT id1 FROM src1 cross join src2 left join src3 on src1.id = src3.id",
  903. data: &xsql.WindowTuples{
  904. Content: []xsql.TupleRow{
  905. &xsql.Tuple{
  906. Emitter: "src2",
  907. Message: xsql.Message{"id": 1, "f2": "w1"},
  908. },
  909. &xsql.Tuple{
  910. Emitter: "src2",
  911. Message: xsql.Message{"id": 2, "f2": "w2"},
  912. },
  913. &xsql.Tuple{
  914. Emitter: "src2",
  915. Message: xsql.Message{"id": 4, "f2": "w3"},
  916. },
  917. &xsql.Tuple{
  918. Emitter: "src3",
  919. Message: xsql.Message{"id": 1, "f3": "x1"},
  920. },
  921. &xsql.Tuple{
  922. Emitter: "src3",
  923. Message: xsql.Message{"id": 5, "f3": "x5"},
  924. },
  925. },
  926. },
  927. result: nil,
  928. },
  929. { // 19
  930. sql: "SELECT id1 FROM src1 full join src2 on src1.id = src2.id full join src3 on src1.id = src3.id",
  931. data: &xsql.WindowTuples{
  932. Content: []xsql.TupleRow{
  933. &xsql.Tuple{
  934. Emitter: "src1",
  935. Message: xsql.Message{"id": 1, "f1": "v1"},
  936. },
  937. &xsql.Tuple{
  938. Emitter: "src2",
  939. Message: xsql.Message{"id": 1, "f2": "w1"},
  940. },
  941. &xsql.Tuple{
  942. Emitter: "src3",
  943. Message: xsql.Message{"id": 1, "f3": "x1"},
  944. },
  945. },
  946. },
  947. result: &xsql.JoinTuples{
  948. Content: []*xsql.JoinTuple{
  949. {
  950. Tuples: []xsql.TupleRow{
  951. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  952. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  953. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  954. },
  955. },
  956. },
  957. },
  958. },
  959. { // 20
  960. sql: "SELECT id1 FROM src1 full join src2 on src1.id = src2.id full join src3 on src1.id = src3.id",
  961. data: &xsql.WindowTuples{
  962. Content: []xsql.TupleRow{
  963. &xsql.Tuple{
  964. Emitter: "src2",
  965. Message: xsql.Message{"id": 1, "f2": "w1"},
  966. },
  967. &xsql.Tuple{
  968. Emitter: "src3",
  969. Message: xsql.Message{"id": 1, "f3": "x1"},
  970. },
  971. },
  972. },
  973. result: &xsql.JoinTuples{
  974. Content: []*xsql.JoinTuple{
  975. {
  976. Tuples: []xsql.TupleRow{
  977. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  978. },
  979. },
  980. {
  981. Tuples: []xsql.TupleRow{
  982. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  983. },
  984. },
  985. },
  986. },
  987. },
  988. { // 21
  989. sql: "SELECT id1 FROM src1 full join src2 on src1.id = src2.id full join src3 on src1.id = src3.id",
  990. data: &xsql.WindowTuples{
  991. Content: []xsql.TupleRow{
  992. &xsql.Tuple{
  993. Emitter: "src1",
  994. Message: xsql.Message{"id": 1, "f1": "v1"},
  995. },
  996. &xsql.Tuple{
  997. Emitter: "src2",
  998. Message: xsql.Message{"id": 1, "f2": "w1"},
  999. },
  1000. },
  1001. },
  1002. result: &xsql.JoinTuples{
  1003. Content: []*xsql.JoinTuple{
  1004. {
  1005. Tuples: []xsql.TupleRow{
  1006. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  1007. &xsql.Tuple{Emitter: "src2", Message: xsql.Message{"id": 1, "f2": "w1"}},
  1008. },
  1009. },
  1010. },
  1011. },
  1012. },
  1013. { // 22
  1014. sql: "SELECT id1 FROM src1 full join src2 on src1.id = src2.id full join src3 on src1.id = src3.id",
  1015. data: &xsql.WindowTuples{
  1016. Content: []xsql.TupleRow{
  1017. &xsql.Tuple{
  1018. Emitter: "src1",
  1019. Message: xsql.Message{"id": 1, "f1": "v1"},
  1020. },
  1021. &xsql.Tuple{
  1022. Emitter: "src3",
  1023. Message: xsql.Message{"id": 1, "f3": "x1"},
  1024. },
  1025. },
  1026. },
  1027. result: &xsql.JoinTuples{
  1028. Content: []*xsql.JoinTuple{
  1029. {
  1030. Tuples: []xsql.TupleRow{
  1031. &xsql.Tuple{Emitter: "src1", Message: xsql.Message{"id": 1, "f1": "v1"}},
  1032. &xsql.Tuple{Emitter: "src3", Message: xsql.Message{"id": 1, "f3": "x1"}},
  1033. },
  1034. },
  1035. },
  1036. },
  1037. },
  1038. }
  1039. fmt.Printf("The test bucket size is %d.\n\n", len(tests))
  1040. contextLogger := conf.Log.WithField("rule", "TestMultiJoinPlan_Apply")
  1041. ctx := context.WithValue(context.Background(), context.LoggerKey, contextLogger)
  1042. for i, tt := range tests {
  1043. stmt, err := xsql.NewParser(strings.NewReader(tt.sql)).Parse()
  1044. if err != nil {
  1045. t.Errorf("statement parse error %s", err)
  1046. break
  1047. }
  1048. if table, ok := stmt.Sources[0].(*ast.Table); !ok {
  1049. t.Errorf("statement source is not a table")
  1050. } else {
  1051. fv, afv := xsql.NewFunctionValuersForOp(nil)
  1052. pp := &JoinOp{Joins: stmt.Joins, From: table}
  1053. result := pp.Apply(ctx, tt.data, fv, afv)
  1054. if !reflect.DeepEqual(tt.result, result) {
  1055. t.Errorf("%d. %q\n\nresult mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.sql, tt.result, result)
  1056. }
  1057. }
  1058. }
  1059. }