tokenizer.subquery.test.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. var Tokenizer = require('../../../index').query.tokenizer;
  2. var assert = require('assert');
  3. describe('Tokenizer ::', function() {
  4. describe('Subqueries ::', function() {
  5. describe('used as a predicate', function() {
  6. it('should generate a valid token array for an IN subquery', function() {
  7. var result = Tokenizer({
  8. select: ['*'],
  9. from: 'accounts',
  10. where: {
  11. and: [
  12. {
  13. id: {
  14. in: {
  15. select: ['id'],
  16. from: 'users',
  17. where: {
  18. or: [
  19. { status: 'active' },
  20. { name: 'John' }
  21. ]
  22. }
  23. }
  24. }
  25. }
  26. ]
  27. }
  28. });
  29. assert.deepEqual(result, [
  30. { type: 'IDENTIFIER', value: 'SELECT' },
  31. { type: 'VALUE', value: '*' },
  32. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  33. { type: 'IDENTIFIER', value: 'FROM' },
  34. { type: 'VALUE', value: 'accounts' },
  35. { type: 'ENDIDENTIFIER', value: 'FROM' },
  36. { type: 'IDENTIFIER', value: 'WHERE' },
  37. { type: 'CONDITION', value: 'AND' },
  38. { type: 'GROUP', value: 0 },
  39. { type: 'KEY', value: 'id' },
  40. { type: 'CONDITION', value: 'IN' },
  41. { type: 'SUBQUERY', value: null },
  42. { type: 'IDENTIFIER', value: 'SELECT' },
  43. { type: 'VALUE', value: 'id' },
  44. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  45. { type: 'IDENTIFIER', value: 'FROM' },
  46. { type: 'VALUE', value: 'users' },
  47. { type: 'ENDIDENTIFIER', value: 'FROM' },
  48. { type: 'IDENTIFIER', value: 'WHERE' },
  49. { type: 'CONDITION', value: 'OR' },
  50. { type: 'GROUP', value: 0 },
  51. { type: 'KEY', value: 'status' },
  52. { type: 'VALUE', value: 'active' },
  53. { type: 'ENDGROUP', value: 0 },
  54. { type: 'GROUP', value: 1 },
  55. { type: 'KEY', value: 'name' },
  56. { type: 'VALUE', value: 'John' },
  57. { type: 'ENDGROUP', value: 1 },
  58. { type: 'ENDCONDITION', value: 'OR' },
  59. { type: 'ENDIDENTIFIER', value: 'WHERE' },
  60. { type: 'ENDSUBQUERY', value: null },
  61. { type: 'ENDCONDITION', value: 'IN' },
  62. { type: 'ENDGROUP', value: 0 },
  63. { type: 'ENDCONDITION', value: 'AND' },
  64. { type: 'ENDIDENTIFIER', value: 'WHERE' }
  65. ]);
  66. });
  67. it('should generate a valid token array for a NOT IN subquery', function() {
  68. var result = Tokenizer({
  69. select: ['*'],
  70. from: 'accounts',
  71. where: {
  72. and: [
  73. {
  74. id: {
  75. nin: {
  76. select: ['id'],
  77. from: 'users',
  78. where: {
  79. or: [
  80. { status: 'active' },
  81. { name: 'John' }
  82. ]
  83. }
  84. }
  85. }
  86. }
  87. ]
  88. }
  89. });
  90. assert.deepEqual(result, [
  91. { type: 'IDENTIFIER', value: 'SELECT' },
  92. { type: 'VALUE', value: '*' },
  93. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  94. { type: 'IDENTIFIER', value: 'FROM' },
  95. { type: 'VALUE', value: 'accounts' },
  96. { type: 'ENDIDENTIFIER', value: 'FROM' },
  97. { type: 'IDENTIFIER', value: 'WHERE' },
  98. { type: 'CONDITION', value: 'AND' },
  99. { type: 'GROUP', value: 0 },
  100. { type: 'KEY', value: 'id' },
  101. { type: 'CONDITION', value: 'NOTIN' },
  102. { type: 'SUBQUERY', value: null },
  103. { type: 'IDENTIFIER', value: 'SELECT' },
  104. { type: 'VALUE', value: 'id' },
  105. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  106. { type: 'IDENTIFIER', value: 'FROM' },
  107. { type: 'VALUE', value: 'users' },
  108. { type: 'ENDIDENTIFIER', value: 'FROM' },
  109. { type: 'IDENTIFIER', value: 'WHERE' },
  110. { type: 'CONDITION', value: 'OR' },
  111. { type: 'GROUP', value: 0 },
  112. { type: 'KEY', value: 'status' },
  113. { type: 'VALUE', value: 'active' },
  114. { type: 'ENDGROUP', value: 0 },
  115. { type: 'GROUP', value: 1 },
  116. { type: 'KEY', value: 'name' },
  117. { type: 'VALUE', value: 'John' },
  118. { type: 'ENDGROUP', value: 1 },
  119. { type: 'ENDCONDITION', value: 'OR' },
  120. { type: 'ENDIDENTIFIER', value: 'WHERE' },
  121. { type: 'ENDSUBQUERY', value: null },
  122. { type: 'ENDCONDITION', value: 'NOTIN' },
  123. { type: 'ENDGROUP', value: 0 },
  124. { type: 'ENDCONDITION', value: 'AND' },
  125. { type: 'ENDIDENTIFIER', value: 'WHERE' }
  126. ]);
  127. });
  128. }); // </ predicate >
  129. describe('used as scalar values', function() {
  130. it('should generate a valid token array when used inside a SELECT', function() {
  131. var result = Tokenizer({
  132. select: ['name', {
  133. select: ['username'],
  134. from: 'users',
  135. where: {
  136. or: [
  137. { status: 'active' },
  138. { name: 'John' }
  139. ]
  140. },
  141. as: 'username'
  142. }, 'age'],
  143. from: 'accounts'
  144. });
  145. assert.deepEqual(result, [
  146. { type: 'IDENTIFIER', value: 'SELECT' },
  147. { type: 'VALUE', value: 'name' },
  148. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  149. { type: 'IDENTIFIER', value: 'SELECT' },
  150. { type: 'SUBQUERY', value: null },
  151. { type: 'IDENTIFIER', value: 'SELECT' },
  152. { type: 'VALUE', value: 'username' },
  153. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  154. { type: 'IDENTIFIER', value: 'FROM' },
  155. { type: 'VALUE', value: 'users' },
  156. { type: 'ENDIDENTIFIER', value: 'FROM' },
  157. { type: 'IDENTIFIER', value: 'WHERE' },
  158. { type: 'CONDITION', value: 'OR' },
  159. { type: 'GROUP', value: 0 },
  160. { type: 'KEY', value: 'status' },
  161. { type: 'VALUE', value: 'active' },
  162. { type: 'ENDGROUP', value: 0 },
  163. { type: 'GROUP', value: 1 },
  164. { type: 'KEY', value: 'name' },
  165. { type: 'VALUE', value: 'John' },
  166. { type: 'ENDGROUP', value: 1 },
  167. { type: 'ENDCONDITION', value: 'OR' },
  168. { type: 'ENDIDENTIFIER', value: 'WHERE' },
  169. { type: 'IDENTIFIER', value: 'AS' },
  170. { type: 'VALUE', value: 'username' },
  171. { type: 'ENDIDENTIFIER', value: 'AS' },
  172. { type: 'ENDSUBQUERY', value: null },
  173. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  174. { type: 'IDENTIFIER', value: 'SELECT' },
  175. { type: 'VALUE', value: 'age' },
  176. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  177. { type: 'IDENTIFIER', value: 'FROM' },
  178. { type: 'VALUE', value: 'accounts' },
  179. { type: 'ENDIDENTIFIER', value: 'FROM' }
  180. ]);
  181. });
  182. it('should generate a valid token array when used as a value in a WHERE', function() {
  183. var result = Tokenizer({
  184. select: ['name', 'age'],
  185. from: 'accounts',
  186. where: {
  187. and: [
  188. {
  189. username: {
  190. select: ['username'],
  191. from: 'users',
  192. where: {
  193. color: 'accounts.color'
  194. }
  195. }
  196. }
  197. ]
  198. }
  199. });
  200. assert.deepEqual(result, [
  201. { type: 'IDENTIFIER', value: 'SELECT' },
  202. { type: 'VALUE', value: 'name' },
  203. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  204. { type: 'IDENTIFIER', value: 'SELECT' },
  205. { type: 'VALUE', value: 'age' },
  206. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  207. { type: 'IDENTIFIER', value: 'FROM' },
  208. { type: 'VALUE', value: 'accounts' },
  209. { type: 'ENDIDENTIFIER', value: 'FROM' },
  210. { type: 'IDENTIFIER', value: 'WHERE' },
  211. { type: 'CONDITION', value: 'AND' },
  212. { type: 'GROUP', value: 0 },
  213. { type: 'KEY', value: 'username' },
  214. { type: 'SUBQUERY', value: null },
  215. { type: 'IDENTIFIER', value: 'SELECT' },
  216. { type: 'VALUE', value: 'username' },
  217. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  218. { type: 'IDENTIFIER', value: 'FROM' },
  219. { type: 'VALUE', value: 'users' },
  220. { type: 'ENDIDENTIFIER', value: 'FROM' },
  221. { type: 'IDENTIFIER', value: 'WHERE' },
  222. { type: 'KEY', value: 'color' },
  223. { type: 'VALUE', value: 'accounts.color' },
  224. { type: 'ENDIDENTIFIER', value: 'WHERE' },
  225. { type: 'ENDSUBQUERY', value: null },
  226. { type: 'ENDGROUP', value: 0 },
  227. { type: 'ENDCONDITION', value: 'AND' },
  228. { type: 'ENDIDENTIFIER', value: 'WHERE' }
  229. ]);
  230. });
  231. }); // </ scalar >
  232. describe('used as table sub query', function() {
  233. it('should generate a valid token array when used as a value in a FROM with an AS alias', function() {
  234. var result = Tokenizer({
  235. select: ['name', 'age'],
  236. from: {
  237. select: ['age'],
  238. from: 'users',
  239. where: {
  240. and: [
  241. {
  242. age: 21
  243. }
  244. ]
  245. },
  246. as: 'userage'
  247. }
  248. });
  249. assert.deepEqual(result, [
  250. { type: 'IDENTIFIER', value: 'SELECT' },
  251. { type: 'VALUE', value: 'name' },
  252. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  253. { type: 'IDENTIFIER', value: 'SELECT' },
  254. { type: 'VALUE', value: 'age' },
  255. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  256. { type: 'IDENTIFIER', value: 'FROM' },
  257. { type: 'SUBQUERY', value: null },
  258. { type: 'IDENTIFIER', value: 'SELECT' },
  259. { type: 'VALUE', value: 'age' },
  260. { type: 'ENDIDENTIFIER', value: 'SELECT' },
  261. { type: 'IDENTIFIER', value: 'FROM' },
  262. { type: 'VALUE', value: 'users' },
  263. { type: 'ENDIDENTIFIER', value: 'FROM' },
  264. { type: 'IDENTIFIER', value: 'WHERE' },
  265. { type: 'CONDITION', value: 'AND' },
  266. { type: 'GROUP', value: 0 },
  267. { type: 'KEY', value: 'age' },
  268. { type: 'VALUE', value: 21 },
  269. { type: 'ENDGROUP', value: 0 },
  270. { type: 'ENDCONDITION', value: 'AND' },
  271. { type: 'ENDIDENTIFIER', value: 'WHERE' },
  272. { type: 'IDENTIFIER', value: 'AS' },
  273. { type: 'VALUE', value: 'userage' },
  274. { type: 'ENDIDENTIFIER', value: 'AS' },
  275. { type: 'ENDSUBQUERY', value: null },
  276. { type: 'ENDIDENTIFIER', value: 'FROM' }
  277. ]);
  278. });
  279. }); // </ table >
  280. });
  281. });