join_multi_test.go 29 KB

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