tparsesql.nim 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. discard """
  2. matrix: "--mm:refc; --mm:orc"
  3. targets: "c js"
  4. """
  5. import parsesql
  6. import std/assertions
  7. doAssert treeRepr(parseSql("INSERT INTO STATS VALUES (10, 5.5); ")
  8. ) == """
  9. nkStmtList
  10. nkInsert
  11. nkIdent STATS
  12. nkNone
  13. nkValueList
  14. nkIntegerLit 10
  15. nkNumericLit 5.5"""
  16. doAssert $parseSql("SELECT foo FROM table;") == "select foo from table;"
  17. doAssert $parseSql("""
  18. SELECT
  19. CustomerName,
  20. ContactName,
  21. Address,
  22. City,
  23. PostalCode,
  24. Country,
  25. CustomerName,
  26. ContactName,
  27. Address,
  28. City,
  29. PostalCode,
  30. Country
  31. FROM table;""") == "select CustomerName, ContactName, Address, City, PostalCode, Country, CustomerName, ContactName, Address, City, PostalCode, Country from table;"
  32. doAssert $parseSql("SELECT foo FROM table limit 10") == "select foo from table limit 10;"
  33. doAssert $parseSql("SELECT foo, bar, baz FROM table limit 10") == "select foo, bar, baz from table limit 10;"
  34. doAssert $parseSql("SELECT foo AS bar FROM table") == "select foo as bar from table;"
  35. doAssert $parseSql("SELECT foo AS foo_prime, bar AS bar_prime, baz AS baz_prime FROM table") == "select foo as foo_prime, bar as bar_prime, baz as baz_prime from table;"
  36. doAssert $parseSql("SELECT * FROM table") == "select * from table;"
  37. doAssert $parseSql("SELECT count(*) FROM table") == "select count(*) from table;"
  38. doAssert $parseSql("SELECT count(*) as 'Total' FROM table") == "select count(*) as 'Total' from table;"
  39. doAssert $parseSql("SELECT count(*) as 'Total', sum(a) as 'Aggr' FROM table") == "select count(*) as 'Total', sum(a) as 'Aggr' from table;"
  40. doAssert $parseSql("""
  41. SELECT * FROM table
  42. WHERE a = b and c = d
  43. """) == "select * from table where a = b and c = d;"
  44. doAssert $parseSql("""
  45. SELECT * FROM table
  46. WHERE not b
  47. """) == "select * from table where not b;"
  48. doAssert $parseSql("""
  49. SELECT
  50. *
  51. FROM
  52. table
  53. WHERE
  54. a and not b
  55. """) == "select * from table where a and not b;"
  56. doAssert $parseSql("""
  57. SELECT * FROM table
  58. ORDER BY 1
  59. """) == "select * from table order by 1;"
  60. doAssert $parseSql("""
  61. SELECT * FROM table
  62. GROUP BY 1
  63. ORDER BY 1
  64. """) == "select * from table group by 1 order by 1;"
  65. doAssert $parseSql("""
  66. SELECT * FROM table
  67. ORDER BY 1
  68. LIMIT 100
  69. """) == "select * from table order by 1 limit 100;"
  70. doAssert $parseSql("""
  71. SELECT * FROM table
  72. WHERE a = b and c = d or n is null and not b + 1 = 3
  73. """) == "select * from table where a = b and c = d or n is null and not b + 1 = 3;"
  74. doAssert $parseSql("""
  75. SELECT * FROM table
  76. WHERE (a = b and c = d) or (n is null and not b + 1 = 3)
  77. """) == "select * from table where(a = b and c = d) or (n is null and not b + 1 = 3);"
  78. doAssert $parseSql("""
  79. SELECT * FROM table
  80. HAVING a = b and c = d
  81. """) == "select * from table having a = b and c = d;"
  82. doAssert $parseSql("""
  83. SELECT a, b FROM table
  84. GROUP BY a
  85. """) == "select a, b from table group by a;"
  86. doAssert $parseSql("""
  87. SELECT a, b FROM table
  88. GROUP BY 1, 2
  89. """) == "select a, b from table group by 1, 2;"
  90. doAssert $parseSql("SELECT t.a FROM t as t") == "select t.a from t as t;"
  91. doAssert $parseSql("""
  92. SELECT a, b FROM (
  93. SELECT * FROM t
  94. )
  95. """) == "select a, b from(select * from t);"
  96. doAssert $parseSql("""
  97. SELECT a, b FROM (
  98. SELECT * FROM t
  99. ) as foo
  100. """) == "select a, b from(select * from t) as foo;"
  101. doAssert $parseSql("""
  102. SELECT a, b FROM (
  103. SELECT * FROM (
  104. SELECT * FROM (
  105. SELECT * FROM (
  106. SELECT * FROM innerTable as inner1
  107. ) as inner2
  108. ) as inner3
  109. ) as inner4
  110. ) as inner5
  111. """) == "select a, b from(select * from(select * from(select * from(select * from innerTable as inner1) as inner2) as inner3) as inner4) as inner5;"
  112. doAssert $parseSql("""
  113. SELECT a, b FROM
  114. (SELECT * FROM a),
  115. (SELECT * FROM b),
  116. (SELECT * FROM c)
  117. """) == "select a, b from(select * from a),(select * from b),(select * from c);"
  118. doAssert $parseSql("""
  119. SELECT * FROM Products
  120. WHERE Price BETWEEN 10 AND 20;
  121. """) == "select * from Products where Price between 10 and 20;"
  122. doAssert $parseSql("""
  123. SELECT id FROM a
  124. JOIN b
  125. ON a.id == b.id
  126. """) == "select id from a join b on a.id == b.id;"
  127. doAssert $parseSql("""
  128. SELECT id FROM a
  129. JOIN (SELECT id from c) as b
  130. ON a.id == b.id
  131. """) == "select id from a join(select id from c) as b on a.id == b.id;"
  132. doAssert $parseSql("""
  133. SELECT id FROM a
  134. INNER JOIN b
  135. ON a.id == b.id
  136. """) == "select id from a inner join b on a.id == b.id;"
  137. # For OUTER joins, LEFT | RIGHT | FULL specifier is not optional
  138. doAssertRaises(SqlParseError): discard parseSql("""
  139. SELECT id FROM a
  140. OUTER JOIN b
  141. ON a.id = b.id
  142. """)
  143. # For NATURAL JOIN and CROSS JOIN, ON and USING clauses are forbidden
  144. doAssertRaises(SqlParseError): discard parseSql("""
  145. SELECT id FROM a
  146. CROSS JOIN b
  147. ON a.id = b.id
  148. """)
  149. # JOIN should parse as part of FROM, not after WHERE
  150. doAssertRaises(SqlParseError): discard parseSql("""
  151. SELECT id FROM a
  152. WHERE a.id IS NOT NULL
  153. INNER JOIN b
  154. ON a.id = b.id
  155. """)
  156. # JOIN should parse as part of FROM, other fromItems may follow
  157. doAssert $parseSql("""
  158. SELECT id
  159. FROM
  160. a JOIN b ON a.id = b.id,
  161. c
  162. """) == "select id from a join b on a.id = b.id, c;"
  163. # LEFT JOIN should parse
  164. doAssert $parseSql("""
  165. SELECT id FROM a
  166. LEFT JOIN b
  167. ON a.id = b.id
  168. """) == "select id from a left join b on a.id = b.id;"
  169. # NATURAL JOIN should parse
  170. doAssert $parseSql("""
  171. SELECT id FROM a
  172. NATURAL JOIN b
  173. """) == "select id from a natural join b;"
  174. # USING should parse
  175. doAssert $parseSql("""
  176. SELECT id FROM a
  177. JOIN b
  178. USING (id)
  179. """) == "select id from a join b using (id );"
  180. # Multiple JOINs should parse
  181. doAssert $parseSql("""
  182. SELECT id FROM a
  183. JOIN b
  184. ON a.id = b.id
  185. LEFT JOIN c
  186. USING (id)
  187. """) == "select id from a join b on a.id = b.id left join c using (id );"
  188. # Parenthesized JOIN expressions should parse
  189. doAssert $parseSql("""
  190. SELECT id
  191. FROM a JOIN (b JOIN c USING (id)) ON a.id = b.id
  192. """) == "select id from a join(b join c using (id )) on a.id = b.id;"
  193. # Left-side parenthesized JOIN expressions should parse
  194. doAssert $parseSql("""
  195. SELECT id
  196. FROM (b JOIN c USING (id)) JOIN a ON a.id = b.id
  197. """) == "select id from b join c using (id ) join a on a.id = b.id;"
  198. doAssert $parseSql("""
  199. CREATE TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
  200. CREATE TABLE holidays (
  201. num_weeks int,
  202. happiness happiness
  203. );
  204. CREATE INDEX table1_attr1 ON table1(attr1);
  205. SELECT * FROM myTab WHERE col1 = 'happy';
  206. """) == "create type happiness as enum ('happy' , 'very happy' , 'ecstatic' ); create table holidays(num_weeks int , happiness happiness );; create index table1_attr1 on table1(attr1 );; select * from myTab where col1 = 'happy';"
  207. doAssert $parseSql("""
  208. INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country)
  209. VALUES ('Cardinal', 'Tom B. Erichsen', 'Skagen 21', 'Stavanger', '4006', 'Norway');
  210. """) == "insert into Customers (CustomerName , ContactName , Address , City , PostalCode , Country ) values ('Cardinal' , 'Tom B. Erichsen' , 'Skagen 21' , 'Stavanger' , '4006' , 'Norway' );"
  211. doAssert $parseSql("""
  212. INSERT INTO TableName DEFAULT VALUES
  213. """) == "insert into TableName default values;"
  214. doAssert $parseSql("""
  215. UPDATE Customers
  216. SET ContactName = 'Alfred Schmidt', City= 'Frankfurt'
  217. WHERE CustomerID = 1;
  218. """) == "update Customers set ContactName = 'Alfred Schmidt' , City = 'Frankfurt' where CustomerID = 1;"
  219. doAssert treeRepr(parseSql("""UPDATE Customers
  220. SET ContactName = 'Alice', City= 'Frankfurt';""")
  221. ) == """
  222. nkStmtList
  223. nkUpdate
  224. nkIdent Customers
  225. nkAsgn
  226. nkIdent ContactName
  227. nkStringLit Alice
  228. nkAsgn
  229. nkIdent City
  230. nkStringLit Frankfurt
  231. nkNone"""
  232. doAssert $parseSql("DELETE FROM table_name;") == "delete from table_name;"
  233. doAssert treeRepr(parseSql("DELETE FROM table_name;")
  234. ) == """
  235. nkStmtList
  236. nkDelete
  237. nkIdent table_name
  238. nkNone"""
  239. doAssert $parseSql("DELETE * FROM table_name;") == "delete from table_name;"
  240. doAssert $parseSql("""
  241. --Select all:
  242. SELECT * FROM Customers;
  243. """) == "select * from Customers;"
  244. doAssert $parseSql("""
  245. SELECT * FROM Customers WHERE (CustomerName LIKE 'L%'
  246. OR CustomerName LIKE 'R%' /*OR CustomerName LIKE 'S%'
  247. OR CustomerName LIKE 'T%'*/ OR CustomerName LIKE 'W%')
  248. AND Country='USA'
  249. ORDER BY CustomerName;
  250. """) == "select * from Customers where(CustomerName like 'L%' or CustomerName like 'R%' or CustomerName like 'W%') and Country = 'USA' order by CustomerName;"
  251. # parse quoted keywords as identifires
  252. doAssert $parseSql("""
  253. SELECT `SELECT`, `FROM` as `GROUP` FROM `WHERE`;
  254. """) == """select "SELECT", "FROM" as "GROUP" from "WHERE";"""
  255. doAssert $parseSql("""
  256. SELECT "SELECT", "FROM" as "GROUP" FROM "WHERE";
  257. """) == """select "SELECT", "FROM" as "GROUP" from "WHERE";"""